]> granicus.if.org Git - libnl/commitdiff
lib/route: Allow override of IFLA_AF_SPEC nesting
authorJef Oliver <jef.oliver@intel.com>
Thu, 1 Sep 2016 00:27:08 +0000 (17:27 -0700)
committerThomas Haller <thaller@redhat.com>
Sat, 24 Sep 2016 11:51:29 +0000 (13:51 +0200)
This patch adds the ability to override nesting into an AF specific
attribute. An example of this is the bridge module.

Regular Nesting:
[IFLA_AF_SPEC]
    [AF_INET]
        [AF_INET_ATTRS]

Bridge Nesting:
[IFLA_AF_SPEC]
    [AF_BRIDGE_ATTRS]

This patch adds ao_fill_af_no_nest to struct rtnl_link_af_ops.
When set to non-zero, this will override the nested AF attribute
and allow nesting of attributes directly into IFLA_AF_SPEC.

Signed-off-by: Jef Oliver <jef.oliver@intel.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
include/netlink-private/route/link/api.h
lib/route/link.c

index 2767f6393476fc2bc1ecf418bba33562c6e0cb67..a3915a3199083dc341ed01ffaf1f279dc9254688 100644 (file)
@@ -167,6 +167,14 @@ struct rtnl_link_af_ops
         * here. (eg. NLA_F_NESTED)
         */
        const int ao_fill_pi_flags;
+
+       /** IFLA_AF_SPEC nesting override
+        *
+        * Called if a link message is sent to the kernel. If this is set,
+        * the AF specific nest is not created. Instead, AF specific attributes
+     * are nested directly in the IFLA_AF_SPEC attribute.
+        */
+        const int ao_fill_af_no_nest;
 };
 
 extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int);
index c24760385e903e616b7b8d6434ba0ea009c2f6bb..90d7a55072aafd4cb6c6130e453c5e638d1703fc 100644 (file)
@@ -135,19 +135,21 @@ static int af_fill(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
                   void *data, void *arg)
 {
        struct nl_msg *msg = arg;
-       struct nlattr *af_attr;
+       struct nlattr *af_attr = NULL;
        int err;
 
        if (!ops->ao_fill_af)
                return 0;
 
-       if (!(af_attr = nla_nest_start(msg, ops->ao_family)))
-               return -NLE_MSGSIZE;
+       if (!ops->ao_fill_af_no_nest)
+               if (!(af_attr = nla_nest_start(msg, ops->ao_family)))
+                       return -NLE_MSGSIZE;
 
        if ((err = ops->ao_fill_af(link, arg, data)) < 0)
                return err;
 
-       nla_nest_end(msg, af_attr);
+       if (!ops->ao_fill_af_no_nest)
+               nla_nest_end(msg, af_attr);
 
        return 0;
 }