{
struct sw_flow_actions *sfa;
- if (n_actions > (PAGE_SIZE - sizeof *sfa) / sizeof(union odp_action))
+ /* At least DP_MAX_PORTS actions are required to be able to flood a
+ * packet to every port. Factor of 2 allows for setting VLAN tags,
+ * etc. */
+ if (n_actions > 2 * DP_MAX_PORTS)
return ERR_PTR(-EINVAL);
sfa = kmalloc(sizeof *sfa + n_actions * sizeof(union odp_action),
/* RCU callback used by flow_deferred_free_acts. */
static void rcu_free_acts_callback(struct rcu_head *rcu)
{
- struct sw_flow_actions *sf_acts = container_of(rcu,
+ struct sw_flow_actions *sf_acts = container_of(rcu,
struct sw_flow_actions, rcu);
kfree(sf_acts);
}
struct tcphdr *tcp = tcp_hdr(skb);
key->tp_src = tcp->source;
key->tp_dst = tcp->dest;
- } else {
- /* Avoid tricking other code into
- * thinking that this packet has an L4
- * header. */
- key->nw_proto = 0;
}
} else if (key->nw_proto == IPPROTO_UDP) {
if (udphdr_ok(skb)) {
struct udphdr *udp = udp_hdr(skb);
key->tp_src = udp->source;
key->tp_dst = udp->dest;
- } else {
- /* Avoid tricking other code into
- * thinking that this packet has an L4
- * header. */
- key->nw_proto = 0;
}
} else if (key->nw_proto == IPPROTO_ICMP) {
if (icmphdr_ok(skb)) {
* in 16-bit network byte order. */
key->tp_src = htons(icmp->type);
key->tp_dst = htons(icmp->code);
- } else {
- /* Avoid tricking other code into
- * thinking that this packet has an L4
- * header. */
- key->nw_proto = 0;
}
}
} else {
key->nw_proto = ntohs(arp->ar_op);
}
- if (key->nw_proto == ARPOP_REQUEST
+ if (key->nw_proto == ARPOP_REQUEST
|| key->nw_proto == ARPOP_REPLY) {
memcpy(&key->nw_src, arp->ar_sip, sizeof(key->nw_src));
memcpy(&key->nw_dst, arp->ar_tip, sizeof(key->nw_dst));