]> git.proxmox.com Git - mirror_ovs.git/blobdiff - datapath/vport.c
cirrus: Use FreeBSD 12.2.
[mirror_ovs.git] / datapath / vport.c
index 56096efc0f73b32325ad7720a089e3ad0bc83b20..bd62c5612398022542b087bded992e3f5cc8b161 100644 (file)
@@ -43,6 +43,7 @@
 
 static LIST_HEAD(vport_ops_list);
 static bool compat_gre_loaded = false;
+static bool compat_ip6_tunnel_loaded = false;
 
 /* Protected by RCU read lock for reading, ovs_mutex for writing. */
 static struct hlist_head *dev_table;
@@ -57,7 +58,7 @@ int ovs_vport_init(void)
 {
        int err;
 
-       dev_table = kzalloc(VPORT_HASH_BUCKETS * sizeof(struct hlist_head),
+       dev_table = kcalloc(VPORT_HASH_BUCKETS, sizeof(struct hlist_head),
                            GFP_KERNEL);
        if (!dev_table)
                return -ENOMEM;
@@ -66,22 +67,37 @@ int ovs_vport_init(void)
        if (err)
                goto err_lisp;
        err = gre_init();
-       if (err && err != -EEXIST)
+       if (err && err != -EEXIST) {
                goto err_gre;
-       else if (err == -EEXIST)
-               pr_warn("Cannot take GRE protocol entry - The ERSPAN feature may not be supported\n");
-       else {
+       } else {
+               if (err == -EEXIST) {
+                       pr_warn("Cannot take GRE protocol rx entry"\
+                               "- The GRE/ERSPAN rx feature not supported\n");
+                       /* continue GRE tx */
+               }
+
                err = ipgre_init();
                if (err && err != -EEXIST) 
                        goto err_ipgre;
                compat_gre_loaded = true;
        }
        err = ip6gre_init();
-       if (err)
+       if (err && err != -EEXIST) {
                goto err_ip6gre;
+       } else {
+               if (err == -EEXIST) {
+                       pr_warn("IPv6 GRE/ERSPAN Rx mode is not supported\n");
+                       goto skip_ip6_tunnel_init;
+               }
+       }
+
        err = ip6_tunnel_init();
        if (err)
                goto err_ip6_tunnel;
+       else
+               compat_ip6_tunnel_loaded = true;
+
+skip_ip6_tunnel_init:
        err = geneve_init_module();
        if (err)
                goto err_geneve;
@@ -127,7 +143,8 @@ void ovs_vport_exit(void)
        ovs_stt_cleanup_module();
        vxlan_cleanup_module();
        geneve_cleanup_module();
-       ip6_tunnel_cleanup();
+       if (compat_ip6_tunnel_loaded)
+               ip6_tunnel_cleanup();
        ip6gre_fini();
        lisp_cleanup_module();
        kfree(dev_table);
@@ -289,6 +306,10 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
                return vport;
        }
 
+       if (parms->type == OVS_VPORT_TYPE_GRE && !compat_gre_loaded) {
+               pr_warn("GRE protocol already loaded!\n");
+               return ERR_PTR(-EAFNOSUPPORT);
+       }
        /* Unlock to attempt module load and return -EAGAIN if load
         * was successful as we need to restart the port addition
         * workflow.
@@ -387,7 +408,7 @@ int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
        if (!vport->ops->get_options)
                return 0;
 
-       nla = nla_nest_start(skb, OVS_VPORT_ATTR_OPTIONS);
+       nla = nla_nest_start_noflag(skb, OVS_VPORT_ATTR_OPTIONS);
        if (!nla)
                return -EMSGSIZE;
 
@@ -486,8 +507,9 @@ u32 ovs_vport_find_upcall_portid(const struct vport *vport, struct sk_buff *skb)
 
        ids = rcu_dereference(vport->upcall_portids);
 
-       if (ids->n_ids == 1 && ids->ids[0] == 0)
-               return 0;
+       /* If there is only one portid, select it in the fast-path. */
+       if (ids->n_ids == 1)
+               return ids->ids[0];
 
        hash = skb_get_hash(skb);
        ids_index = hash - ids->n_ids * reciprocal_divide(hash, ids->rn_ids);