libnl  3.2.21
bridge.c
1 /*
2  * lib/route/link/bridge.c AF_BRIDGE link oeprations
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 #include <netlink-private/netlink.h>
13 #include <netlink/netlink.h>
14 #include <netlink/attr.h>
15 #include <netlink/route/rtnl.h>
16 #include <netlink-private/route/link/api.h>
17 
18 #define BRIDGE_ATTR_PORT_STATE 0x0001
19 
21 {
22  uint8_t b_port_state;
23  uint32_t ce_mask; /* HACK to support attr macros */
24 };
25 
26 static void *bridge_alloc(struct rtnl_link *link)
27 {
28  return calloc(1, sizeof(struct bridge_data));
29 }
30 
31 static void *bridge_clone(struct rtnl_link *link, void *data)
32 {
33  struct bridge_data *bd;
34 
35  if ((bd = bridge_alloc(link)))
36  memcpy(bd, data, sizeof(*bd));
37 
38  return bd;
39 }
40 
41 static void bridge_free(struct rtnl_link *link, void *data)
42 {
43  free(data);
44 }
45 
46 static int bridge_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
47  void *data)
48 {
49  struct bridge_data *bd = data;
50 
51  bd->b_port_state = nla_get_u8(attr);
52  bd->ce_mask |= BRIDGE_ATTR_PORT_STATE;
53 
54  return 0;
55 }
56 
57 static void bridge_dump_details(struct rtnl_link *link,
58  struct nl_dump_params *p, void *data)
59 {
60  struct bridge_data *bd = data;
61 
62  if (bd->ce_mask & BRIDGE_ATTR_PORT_STATE)
63  nl_dump(p, "port-state %u ", bd->b_port_state);
64 }
65 
66 static int bridge_compare(struct rtnl_link *_a, struct rtnl_link *_b,
67  int family, uint32_t attrs, int flags)
68 {
69  struct bridge_data *a = (struct bridge_data *)_a->l_af_data;
70  struct bridge_data *b = (struct bridge_data *)_b->l_af_data;
71  int diff = 0;
72 
73 #define BRIDGE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, BRIDGE_ATTR_##ATTR, a, b, EXPR)
74  diff |= BRIDGE_DIFF(PORT_STATE, a->b_port_state != b->b_port_state);
75 
76  return diff;
77 #undef BRIDGE_DIFF
78 }
79 
80 static const struct nla_policy protinfo_policy = {
81  .type = NLA_U8,
82 };
83 
84 static struct rtnl_link_af_ops bridge_ops = {
85  .ao_family = AF_BRIDGE,
86  .ao_alloc = &bridge_alloc,
87  .ao_clone = &bridge_clone,
88  .ao_free = &bridge_free,
89  .ao_parse_protinfo = &bridge_parse_protinfo,
90  .ao_dump[NL_DUMP_DETAILS] = &bridge_dump_details,
91  .ao_protinfo_policy = &protinfo_policy,
92  .ao_compare = &bridge_compare,
93 };
94 
95 static void __init bridge_init(void)
96 {
97  rtnl_link_af_register(&bridge_ops);
98 }
99 
100 static void __exit bridge_exit(void)
101 {
102  rtnl_link_af_unregister(&bridge_ops);
103 }