igb: use BIT() macro or unsigned prefix
[deliverable/linux.git] / drivers / net / geneve.c
index 7b0a644122ebf064c6058e2aa5bb453cec3d57d1..a6dc11ce497f5c328581ee3db460eb645e3a8fa5 100644 (file)
@@ -87,7 +87,6 @@ struct geneve_sock {
        struct socket           *sock;
        struct rcu_head         rcu;
        int                     refcnt;
-       struct udp_offload      udp_offloads;
        struct hlist_head       vni_list[VNI_HASH_SIZE];
        u32                     flags;
 };
@@ -409,14 +408,6 @@ static void geneve_notify_add_rx_port(struct geneve_sock *gs)
        struct net *net = sock_net(sk);
        sa_family_t sa_family = geneve_get_sk_family(gs);
        __be16 port = inet_sk(sk)->inet_sport;
-       int err;
-
-       if (sa_family == AF_INET) {
-               err = udp_add_offload(sock_net(sk), &gs->udp_offloads);
-               if (err)
-                       pr_warn("geneve: udp_add_offload failed with status %d\n",
-                               err);
-       }
 
        rcu_read_lock();
        for_each_netdev_rcu(net, dev) {
@@ -432,9 +423,9 @@ static int geneve_hlen(struct genevehdr *gh)
        return sizeof(*gh) + gh->opt_len * 4;
 }
 
-static struct sk_buff **geneve_gro_receive(struct sk_buff **head,
-                                          struct sk_buff *skb,
-                                          struct udp_offload *uoff)
+static struct sk_buff **geneve_gro_receive(struct sock *sk,
+                                          struct sk_buff **head,
+                                          struct sk_buff *skb)
 {
        struct sk_buff *p, **pp = NULL;
        struct genevehdr *gh, *gh2;
@@ -495,8 +486,8 @@ out:
        return pp;
 }
 
-static int geneve_gro_complete(struct sk_buff *skb, int nhoff,
-                              struct udp_offload *uoff)
+static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb,
+                              int nhoff)
 {
        struct genevehdr *gh;
        struct packet_offload *ptype;
@@ -546,14 +537,14 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port,
                INIT_HLIST_HEAD(&gs->vni_list[h]);
 
        /* Initialize the geneve udp offloads structure */
-       gs->udp_offloads.port = port;
-       gs->udp_offloads.callbacks.gro_receive  = geneve_gro_receive;
-       gs->udp_offloads.callbacks.gro_complete = geneve_gro_complete;
        geneve_notify_add_rx_port(gs);
 
        /* Mark socket as an encapsulation socket */
+       memset(&tunnel_cfg, 0, sizeof(tunnel_cfg));
        tunnel_cfg.sk_user_data = gs;
        tunnel_cfg.encap_type = 1;
+       tunnel_cfg.gro_receive = geneve_gro_receive;
+       tunnel_cfg.gro_complete = geneve_gro_complete;
        tunnel_cfg.encap_rcv = geneve_udp_encap_recv;
        tunnel_cfg.encap_destroy = NULL;
        setup_udp_tunnel_sock(net, sock, &tunnel_cfg);
@@ -577,9 +568,6 @@ static void geneve_notify_del_rx_port(struct geneve_sock *gs)
        }
 
        rcu_read_unlock();
-
-       if (sa_family == AF_INET)
-               udp_del_offload(&gs->udp_offloads);
 }
 
 static void __geneve_sock_release(struct geneve_sock *gs)
@@ -709,16 +697,12 @@ static int geneve_build_skb(struct rtable *rt, struct sk_buff *skb,
        min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
                        + GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr);
        err = skb_cow_head(skb, min_headroom);
-       if (unlikely(err)) {
-               kfree_skb(skb);
+       if (unlikely(err))
                goto free_rt;
-       }
 
-       skb = udp_tunnel_handle_offloads(skb, udp_sum);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
+       err = udp_tunnel_handle_offloads(skb, udp_sum);
+       if (err)
                goto free_rt;
-       }
 
        gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
        geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
@@ -746,16 +730,12 @@ static int geneve6_build_skb(struct dst_entry *dst, struct sk_buff *skb,
        min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
                        + GENEVE_BASE_HLEN + opt_len + sizeof(struct ipv6hdr);
        err = skb_cow_head(skb, min_headroom);
-       if (unlikely(err)) {
-               kfree_skb(skb);
+       if (unlikely(err))
                goto free_dst;
-       }
 
-       skb = udp_tunnel_handle_offloads(skb, udp_sum);
-       if (IS_ERR(skb)) {
-               err = PTR_ERR(skb);
+       err = udp_tunnel_handle_offloads(skb, udp_sum);
+       if (err)
                goto free_dst;
-       }
 
        gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
        geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
@@ -950,7 +930,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                err = geneve_build_skb(rt, skb, key->tun_flags, vni,
                                       info->options_len, opts, flags, xnet);
                if (unlikely(err))
-                       goto err;
+                       goto tx_error;
 
                tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
                ttl = key->ttl;
@@ -959,7 +939,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                err = geneve_build_skb(rt, skb, 0, geneve->vni,
                                       0, NULL, flags, xnet);
                if (unlikely(err))
-                       goto err;
+                       goto tx_error;
 
                tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
                ttl = geneve->ttl;
@@ -977,7 +957,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 
 tx_error:
        dev_kfree_skb(skb);
-err:
+
        if (err == -ELOOP)
                dev->stats.collisions++;
        else if (err == -ENETUNREACH)
@@ -1039,7 +1019,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                                        info->options_len, opts,
                                        flags, xnet);
                if (unlikely(err))
-                       goto err;
+                       goto tx_error;
 
                prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
                ttl = key->ttl;
@@ -1048,7 +1028,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                err = geneve6_build_skb(dst, skb, 0, geneve->vni,
                                        0, NULL, flags, xnet);
                if (unlikely(err))
-                       goto err;
+                       goto tx_error;
 
                prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
                                           iip, skb);
@@ -1067,7 +1047,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 
 tx_error:
        dev_kfree_skb(skb);
-err:
+
        if (err == -ELOOP)
                dev->stats.collisions++;
        else if (err == -ENETUNREACH)
@@ -1193,7 +1173,7 @@ static struct device_type geneve_type = {
  * supply the listening GENEVE udp ports. Callers are expected
  * to implement the ndo_add_geneve_port.
  */
-void geneve_get_rx_port(struct net_device *dev)
+static void geneve_push_rx_ports(struct net_device *dev)
 {
        struct net *net = dev_net(dev);
        struct geneve_net *gn = net_generic(net, geneve_net_id);
@@ -1202,6 +1182,9 @@ void geneve_get_rx_port(struct net_device *dev)
        struct sock *sk;
        __be16 port;
 
+       if (!dev->netdev_ops->ndo_add_geneve_port)
+               return;
+
        rcu_read_lock();
        list_for_each_entry_rcu(gs, &gn->sock_list, list) {
                sk = gs->sock->sk;
@@ -1211,7 +1194,6 @@ void geneve_get_rx_port(struct net_device *dev)
        }
        rcu_read_unlock();
 }
-EXPORT_SYMBOL_GPL(geneve_get_rx_port);
 
 /* Initialize the device structure. */
 static void geneve_setup(struct net_device *dev)
@@ -1559,6 +1541,21 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
 }
 EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
 
+static int geneve_netdevice_event(struct notifier_block *unused,
+                                 unsigned long event, void *ptr)
+{
+       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+
+       if (event == NETDEV_OFFLOAD_PUSH_GENEVE)
+               geneve_push_rx_ports(dev);
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block geneve_notifier_block __read_mostly = {
+       .notifier_call = geneve_netdevice_event,
+};
+
 static __net_init int geneve_init_net(struct net *net)
 {
        struct geneve_net *gn = net_generic(net, geneve_net_id);
@@ -1611,11 +1608,18 @@ static int __init geneve_init_module(void)
        if (rc)
                goto out1;
 
-       rc = rtnl_link_register(&geneve_link_ops);
+       rc = register_netdevice_notifier(&geneve_notifier_block);
        if (rc)
                goto out2;
 
+       rc = rtnl_link_register(&geneve_link_ops);
+       if (rc)
+               goto out3;
+
        return 0;
+
+out3:
+       unregister_netdevice_notifier(&geneve_notifier_block);
 out2:
        unregister_pernet_subsys(&geneve_net_ops);
 out1:
@@ -1626,6 +1630,7 @@ late_initcall(geneve_init_module);
 static void __exit geneve_cleanup_module(void)
 {
        rtnl_link_unregister(&geneve_link_ops);
+       unregister_netdevice_notifier(&geneve_notifier_block);
        unregister_pernet_subsys(&geneve_net_ops);
 }
 module_exit(geneve_cleanup_module);
This page took 0.027296 seconds and 5 git commands to generate.