]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
link: Add af data compare to link objects
authorroopa <roopa@cumulusnetworks.com>
Fri, 18 Jan 2013 00:29:04 +0000 (16:29 -0800)
committerThomas Graf <tgraf@suug.ch>
Fri, 18 Jan 2013 13:42:18 +0000 (14:42 +0100)
Today the link compare function does not
compare af data of a link. We have found a
need for this to get approriate change callbacks
when af_data of a link changes.

This patch adds support to compare af_data
to link_compare function. This patch today
only adds support to compare af_data set by
PROTINFO attributes. It can be extended to
support compares of af_data set by AF_SPEC
attributes

It has been tested for AF_BRIDGE objects.
In case of AF_BRIDGE objects, this helps with
bridge port change notification callbacks.

Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
lib/route/link.c

index 377135e4c16d66f1126066cc024821f6618813e1..f817b3a52b18202edf20708f56df22d326193326 100644 (file)
@@ -55,6 +55,8 @@
 #define LINK_ATTR_NUM_RX_QUEUES        (1 << 23)
 #define LINK_ATTR_GROUP                (1 << 24)
 #define LINK_ATTR_CARRIER      (1 << 25)
+#define LINK_ATTR_PROTINFO     (1 << 26)
+#define LINK_ATTR_AF_SPEC      (1 << 27)
 
 static struct nl_cache_ops rtnl_link_ops;
 static struct nl_object_ops link_obj_ops;
@@ -522,6 +524,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
                                }
                        }
                }
+               link->ce_mask |= LINK_ATTR_LINKINFO;
        }
 
        if (tb[IFLA_PROTINFO] && af_ops && af_ops->ao_parse_protinfo) {
@@ -529,6 +532,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
                                                link->l_af_data[link->l_family]);
                if (err < 0)
                        goto errout;
+               link->ce_mask |= LINK_ATTR_PROTINFO;
        }
 
        if (tb[IFLA_AF_SPEC]) {
@@ -549,6 +553,7 @@ static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
                        }
 
                }
+               link->ce_mask |= LINK_ATTR_AF_SPEC;
        }
 
        if (tb[IFLA_PROMISCUITY]) {
@@ -851,15 +856,28 @@ static int link_compare(struct nl_object *_a, struct nl_object *_b,
        diff |= LINK_DIFF(NUM_RX_QUEUES,a->l_num_rx_queues != b->l_num_rx_queues);
        diff |= LINK_DIFF(GROUP,        a->l_group != b->l_group);
 
+       /*
+        * Compare LINK_ATTR_PROTINFO af_data
+        */
+       if (a->l_family == b->l_family) {
+               if (rtnl_link_af_data_compare(a, b, a->l_family) != 0)
+                       goto protinfo_mismatch;
+       }
+
        if (flags & LOOSE_COMPARISON)
                diff |= LINK_DIFF(FLAGS,
                                  (a->l_flags ^ b->l_flags) & b->l_flag_mask);
        else
                diff |= LINK_DIFF(FLAGS, a->l_flags != b->l_flags);
 
-#undef LINK_DIFF
-
+out:
        return diff;
+
+protinfo_mismatch:
+       diff |= LINK_DIFF(PROTINFO, 1);
+       goto out;
+
+#undef LINK_DIFF
 }
 
 static const struct trans_tbl link_attrs[] = {