Tue, Feb 21, 2017 at 07:50:53PM CET, t...@herbertland.com wrote: >On Tue, Feb 21, 2017 at 6:33 AM, Jiri Pirko <j...@resnulli.us> wrote: >> From: Jiri Pirko <j...@mellanox.com> >> >> Make the main flow_dissect function a bit smaller and move the ARP >> dissection into a separate function. Along with that, do the ARP header >> processing only in case the flow dissection user requires it. >> > >Acked-by: Tom Herbert <t...@herbertland.com> > >GRE might also be a good candidate to get its own function. >
Submitted with GRE bits. Note that I left you ack and Simon's revby out since I did some cosmetic changes until rfc. I would be glad if you both can check it again. Thanks! > >> Signed-off-by: Jiri Pirko <j...@mellanox.com> >> --- >> net/core/flow_dissector.c | 111 >> ++++++++++++++++++++++++---------------------- >> 1 file changed, 59 insertions(+), 52 deletions(-) >> >> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c >> index c35aae1..10dc5bb 100644 >> --- a/net/core/flow_dissector.c >> +++ b/net/core/flow_dissector.c >> @@ -113,6 +113,61 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, >> int thoff, u8 ip_proto, >> } >> EXPORT_SYMBOL(__skb_flow_get_ports); >> >> +static bool __skb_flow_dissect_arp(const struct sk_buff *skb, >> + struct flow_dissector *flow_dissector, >> + void *target_container, void *data, >> + int nhoff, int hlen) >> +{ >> + struct flow_dissector_key_arp *key_arp; >> + struct { >> + unsigned char ar_sha[ETH_ALEN]; >> + unsigned char ar_sip[4]; >> + unsigned char ar_tha[ETH_ALEN]; >> + unsigned char ar_tip[4]; >> + } *arp_eth, _arp_eth; >> + const struct arphdr *arp; >> + struct arphdr *_arp; >> + >> + if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ARP)) >> + return true; >> + >> + arp = __skb_header_pointer(skb, nhoff, sizeof(_arp), data, >> + hlen, &_arp); >> + if (!arp) >> + return false; >> + >> + if (arp->ar_hrd != htons(ARPHRD_ETHER) || >> + arp->ar_pro != htons(ETH_P_IP) || >> + arp->ar_hln != ETH_ALEN || >> + arp->ar_pln != 4 || >> + (arp->ar_op != htons(ARPOP_REPLY) && >> + arp->ar_op != htons(ARPOP_REQUEST))) >> + return false; >> + >> + arp_eth = __skb_header_pointer(skb, nhoff + sizeof(_arp), >> + sizeof(_arp_eth), data, >> + hlen, &_arp_eth); >> + if (!arp_eth) >> + return false; >> + >> + key_arp = skb_flow_dissector_target(flow_dissector, >> + FLOW_DISSECTOR_KEY_ARP, >> + target_container); >> + >> + memcpy(&key_arp->sip, arp_eth->ar_sip, sizeof(key_arp->sip)); >> + memcpy(&key_arp->tip, arp_eth->ar_tip, sizeof(key_arp->tip)); >> + >> + /* Only store the lower byte of the opcode; >> + * this covers ARPOP_REPLY and ARPOP_REQUEST. >> + */ >> + key_arp->op = ntohs(arp->ar_op) & 0xff; >> + >> + ether_addr_copy(key_arp->sha, arp_eth->ar_sha); >> + ether_addr_copy(key_arp->tha, arp_eth->ar_tha); >> + >> + return true; >> +} >> + >> /** >> * __skb_flow_dissect - extract the flow_keys struct and return it >> * @skb: sk_buff to extract the flow from, can be NULL if the rest are >> specified >> @@ -138,7 +193,6 @@ bool __skb_flow_dissect(const struct sk_buff *skb, >> struct flow_dissector_key_control *key_control; >> struct flow_dissector_key_basic *key_basic; >> struct flow_dissector_key_addrs *key_addrs; >> - struct flow_dissector_key_arp *key_arp; >> struct flow_dissector_key_ports *key_ports; >> struct flow_dissector_key_icmp *key_icmp; >> struct flow_dissector_key_tags *key_tags; >> @@ -382,59 +436,12 @@ bool __skb_flow_dissect(const struct sk_buff *skb, >> goto out_good; >> >> case htons(ETH_P_ARP): >> - case htons(ETH_P_RARP): { >> - struct { >> - unsigned char ar_sha[ETH_ALEN]; >> - unsigned char ar_sip[4]; >> - unsigned char ar_tha[ETH_ALEN]; >> - unsigned char ar_tip[4]; >> - } *arp_eth, _arp_eth; >> - const struct arphdr *arp; >> - struct arphdr *_arp; >> - >> - arp = __skb_header_pointer(skb, nhoff, sizeof(_arp), data, >> - hlen, &_arp); >> - if (!arp) >> - goto out_bad; >> - >> - if (arp->ar_hrd != htons(ARPHRD_ETHER) || >> - arp->ar_pro != htons(ETH_P_IP) || >> - arp->ar_hln != ETH_ALEN || >> - arp->ar_pln != 4 || >> - (arp->ar_op != htons(ARPOP_REPLY) && >> - arp->ar_op != htons(ARPOP_REQUEST))) >> + case htons(ETH_P_RARP): >> + if (!__skb_flow_dissect_arp(skb, flow_dissector, >> + target_container, data, >> + nhoff, hlen)) >> goto out_bad; >> - >> - arp_eth = __skb_header_pointer(skb, nhoff + sizeof(_arp), >> - sizeof(_arp_eth), data, >> - hlen, >> - &_arp_eth); >> - if (!arp_eth) >> - goto out_bad; >> - >> - if (dissector_uses_key(flow_dissector, >> - FLOW_DISSECTOR_KEY_ARP)) { >> - >> - key_arp = skb_flow_dissector_target(flow_dissector, >> - >> FLOW_DISSECTOR_KEY_ARP, >> - >> target_container); >> - >> - memcpy(&key_arp->sip, arp_eth->ar_sip, >> - sizeof(key_arp->sip)); >> - memcpy(&key_arp->tip, arp_eth->ar_tip, >> - sizeof(key_arp->tip)); >> - >> - /* Only store the lower byte of the opcode; >> - * this covers ARPOP_REPLY and ARPOP_REQUEST. >> - */ >> - key_arp->op = ntohs(arp->ar_op) & 0xff; >> - >> - ether_addr_copy(key_arp->sha, arp_eth->ar_sha); >> - ether_addr_copy(key_arp->tha, arp_eth->ar_tha); >> - } >> - >> goto out_good; >> - } >> >> default: >> goto out_bad; >> -- >> 2.7.4 >>