X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=xdp.c;h=74e8e8cb0e850c8556b68877c0faa6de194f51b4;hb=6f38d6623c3282c8f93dedd1b6419946da1311dc;hp=1709e00cfb727e308c541d60441c8ce50c828707;hpb=66e2db182f749072cac361b873dcc35d6377468e;p=flowspec-xdp diff --git a/xdp.c b/xdp.c index 1709e00..74e8e8c 100644 --- a/xdp.c +++ b/xdp.c @@ -226,18 +226,20 @@ int xdp_drop_prog(struct xdp_md *ctx) l4hdr = pktdata + 5*4; #endif - if (ip->protocol == IP_PROTO_TCP) { - if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - tcp = (struct tcphdr*) l4hdr; - } else if (ip->protocol == IP_PROTO_UDP) { - if (unlikely(l4hdr + sizeof(struct udphdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - udp = (struct udphdr*) l4hdr; - } else if (ip->protocol == IP_PROTO_ICMP) { - if (unlikely(l4hdr + sizeof(struct icmphdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - icmp = (struct icmphdr*) l4hdr; + if ((ip->frag_off & BE16(IP_OFFSET)) == 0) { + if (ip->protocol == IP_PROTO_TCP) { + if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + tcp = (struct tcphdr*) l4hdr; + } else if (ip->protocol == IP_PROTO_UDP) { + if (unlikely(l4hdr + sizeof(struct udphdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + udp = (struct udphdr*) l4hdr; + } else if (ip->protocol == IP_PROTO_ICMP) { + if (unlikely(l4hdr + sizeof(struct icmphdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + icmp = (struct icmphdr*) l4hdr; + } } } #endif @@ -264,21 +266,23 @@ int xdp_drop_prog(struct xdp_md *ctx) #endif } #endif - - if (v6nexthdr == IP_PROTO_TCP) { - if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - tcp = (struct tcphdr*) l4hdr; - } else if (v6nexthdr == IP_PROTO_UDP) { - if (unlikely(l4hdr + sizeof(struct udphdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - udp = (struct udphdr*) l4hdr; - } else if (v6nexthdr == IP6_PROTO_ICMPV6) { - if (unlikely(l4hdr + sizeof(struct icmp6hdr) > data_end)) - DO_RETURN(PKT_LEN_DROP, XDP_DROP); - icmpv6 = (struct icmp6hdr*) l4hdr; + // TODO: Handle more options? + + if (frag6 == NULL || (frag6->frag_off & BE16(IP6_FRAGOFF)) == 0) { + if (v6nexthdr == IP_PROTO_TCP) { + if (unlikely(l4hdr + sizeof(struct tcphdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + tcp = (struct tcphdr*) l4hdr; + } else if (v6nexthdr == IP_PROTO_UDP) { + if (unlikely(l4hdr + sizeof(struct udphdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + udp = (struct udphdr*) l4hdr; + } else if (v6nexthdr == IP6_PROTO_ICMPV6) { + if (unlikely(l4hdr + sizeof(struct icmp6hdr) > data_end)) + DO_RETURN(PKT_LEN_DROP, XDP_DROP); + icmpv6 = (struct icmp6hdr*) l4hdr; + } } - // TODO: Handle some options? } #endif