]> Pileus Git - ~andy/linux/blobdiff - net/ipv6/exthdrs.c
ipv6: Switch to using new offload infrastructure.
[~andy/linux] / net / ipv6 / exthdrs.c
index fa3d9c3280927934bd7b082077674c3c31d4ad4c..de6559e3aa0ace735175fdc13188969328a181d0 100644 (file)
@@ -43,7 +43,7 @@
 #include <net/ndisc.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
 #include <net/xfrm.h>
 #endif
 
@@ -224,7 +224,7 @@ bad:
   Destination options header.
  *****************************/
 
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
 static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
 {
        struct ipv6_destopt_hao *hao;
@@ -288,7 +288,7 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
 #endif
 
 static const struct tlvtype_proc tlvprocdestopt_lst[] = {
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
        {
                .type   = IPV6_TLV_HAO,
                .func   = ipv6_dest_hao,
@@ -300,7 +300,7 @@ static const struct tlvtype_proc tlvprocdestopt_lst[] = {
 static int ipv6_destopt_rcv(struct sk_buff *skb)
 {
        struct inet6_skb_parm *opt = IP6CB(skb);
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
        __u16 dstbuf;
 #endif
        struct dst_entry *dst = skb_dst(skb);
@@ -315,14 +315,14 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
        }
 
        opt->lastopt = opt->dst1 = skb_network_header_len(skb);
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
        dstbuf = opt->dst1;
 #endif
 
        if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
                skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
                opt = IP6CB(skb);
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
                opt->nhoff = dstbuf;
 #else
                opt->nhoff = opt->dst1;
@@ -378,7 +378,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
 looped_back:
        if (hdr->segments_left == 0) {
                switch (hdr->type) {
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
                case IPV6_SRCRT_TYPE_2:
                        /* Silently discard type 2 header unless it was
                         * processed by own
@@ -404,7 +404,7 @@ looped_back:
        }
 
        switch (hdr->type) {
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
        case IPV6_SRCRT_TYPE_2:
                if (accept_source_route < 0)
                        goto unknown_rh;
@@ -461,7 +461,7 @@ looped_back:
        addr += i - 1;
 
        switch (hdr->type) {
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+#if IS_ENABLED(CONFIG_IPV6_MIP6)
        case IPV6_SRCRT_TYPE_2:
                if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
                                     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
@@ -531,24 +531,62 @@ static const struct inet6_protocol rthdr_protocol = {
        .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
+static const struct net_offload rthdr_offload = {
+       .flags          =       INET6_PROTO_GSO_EXTHDR,
+};
+
 static const struct inet6_protocol destopt_protocol = {
        .handler        =       ipv6_destopt_rcv,
        .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
+static const struct net_offload dstopt_offload = {
+       .flags          =       INET6_PROTO_GSO_EXTHDR,
+};
+
 static const struct inet6_protocol nodata_protocol = {
        .handler        =       dst_discard,
        .flags          =       INET6_PROTO_NOPOLICY,
 };
 
+static int ipv6_exthdrs_offload_init(void)
+{
+       int ret;
+
+       ret = inet6_add_offload(&rthdr_offload, IPPROTO_ROUTING);
+       if (!ret)
+               goto out;
+
+       ret = inet6_add_offload(&dstopt_offload, IPPROTO_DSTOPTS);
+       if (!ret)
+               goto out_rt;
+
+out:
+       return ret;
+
+out_rt:
+       inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
+       goto out;
+}
+
+static void ipv6_exthdrs_offload_exit(void)
+{
+       inet_del_offload(&rthdr_offload, IPPROTO_ROUTING);
+       inet_del_offload(&rthdr_offload, IPPROTO_DSTOPTS);
+}
+
 int __init ipv6_exthdrs_init(void)
 {
        int ret;
 
-       ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+       ret = ipv6_exthdrs_offload_init();
        if (ret)
                goto out;
 
+       ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+       if (ret)
+               goto out_offload;
+
        ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
        if (ret)
                goto out_rthdr;
@@ -559,10 +597,12 @@ int __init ipv6_exthdrs_init(void)
 
 out:
        return ret;
-out_rthdr:
-       inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
 out_destopt:
        inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
+out_rthdr:
+       inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+out_offload:
+       ipv6_exthdrs_offload_exit();
        goto out;
 };