]> git.proxmox.com Git - pve-kernel-jessie.git/blob - bridge-vlandrange3.patch
add sources for 4.1 based kernel (ubuntu wily)
[pve-kernel-jessie.git] / bridge-vlandrange3.patch
1 From 36cd0ffbab8a65f44ae13fb200bfb5a8f9ea68de Mon Sep 17 00:00:00 2001
2 From: Roopa Prabhu <roopa@cumulusnetworks.com>
3 Date: Sat, 10 Jan 2015 07:31:14 -0800
4 Subject: bridge: new function to pack vlans into ranges during gets
5
6 This patch adds new function to pack vlans into ranges
7 whereever applicable using the flags BRIDGE_VLAN_INFO_RANGE_BEGIN
8 and BRIDGE VLAN_INFO_RANGE_END
9
10 Old vlan packing code is moved to a new function and continues to be
11 called when filter_mask is RTEXT_FILTER_BRVLAN.
12
13 Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15
16 diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
17 index 6f616a2..0b03879 100644
18 --- a/net/bridge/br_netlink.c
19 +++ b/net/bridge/br_netlink.c
20 @@ -67,6 +67,118 @@ static int br_port_fill_attrs(struct sk_buff *skb,
21 return 0;
22 }
23
24 +static int br_fill_ifvlaninfo_range(struct sk_buff *skb, u16 vid_start,
25 + u16 vid_end, u16 flags)
26 +{
27 + struct bridge_vlan_info vinfo;
28 +
29 + if ((vid_end - vid_start) > 0) {
30 + /* add range to skb */
31 + vinfo.vid = vid_start;
32 + vinfo.flags = flags | BRIDGE_VLAN_INFO_RANGE_BEGIN;
33 + if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
34 + sizeof(vinfo), &vinfo))
35 + goto nla_put_failure;
36 +
37 + vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
38 +
39 + vinfo.vid = vid_end;
40 + vinfo.flags = flags | BRIDGE_VLAN_INFO_RANGE_END;
41 + if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
42 + sizeof(vinfo), &vinfo))
43 + goto nla_put_failure;
44 + } else {
45 + vinfo.vid = vid_start;
46 + vinfo.flags = flags;
47 + if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
48 + sizeof(vinfo), &vinfo))
49 + goto nla_put_failure;
50 + }
51 +
52 + return 0;
53 +
54 +nla_put_failure:
55 + return -EMSGSIZE;
56 +}
57 +
58 +static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb,
59 + const struct net_port_vlans *pv)
60 +{
61 + u16 vid_range_start = 0, vid_range_end = 0;
62 + u16 vid_range_flags;
63 + u16 pvid, vid, flags;
64 + int err = 0;
65 +
66 + /* Pack IFLA_BRIDGE_VLAN_INFO's for every vlan
67 + * and mark vlan info with begin and end flags
68 + * if vlaninfo represents a range
69 + */
70 + pvid = br_get_pvid(pv);
71 + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
72 + flags = 0;
73 + if (vid == pvid)
74 + flags |= BRIDGE_VLAN_INFO_PVID;
75 +
76 + if (test_bit(vid, pv->untagged_bitmap))
77 + flags |= BRIDGE_VLAN_INFO_UNTAGGED;
78 +
79 + if (vid_range_start == 0) {
80 + goto initvars;
81 + } else if ((vid - vid_range_end) == 1 &&
82 + flags == vid_range_flags) {
83 + vid_range_end = vid;
84 + continue;
85 + } else {
86 + err = br_fill_ifvlaninfo_range(skb, vid_range_start,
87 + vid_range_end,
88 + vid_range_flags);
89 + if (err)
90 + return err;
91 + }
92 +
93 +initvars:
94 + vid_range_start = vid;
95 + vid_range_end = vid;
96 + vid_range_flags = flags;
97 + }
98 +
99 + /* Call it once more to send any left over vlans */
100 + err = br_fill_ifvlaninfo_range(skb, vid_range_start,
101 + vid_range_end,
102 + vid_range_flags);
103 + if (err)
104 + return err;
105 +
106 + return 0;
107 +}
108 +
109 +static int br_fill_ifvlaninfo(struct sk_buff *skb,
110 + const struct net_port_vlans *pv)
111 +{
112 + struct bridge_vlan_info vinfo;
113 + u16 pvid, vid;
114 +
115 + pvid = br_get_pvid(pv);
116 + for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
117 + vinfo.vid = vid;
118 + vinfo.flags = 0;
119 + if (vid == pvid)
120 + vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
121 +
122 + if (test_bit(vid, pv->untagged_bitmap))
123 + vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
124 +
125 + if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
126 + sizeof(vinfo), &vinfo))
127 + goto nla_put_failure;
128 + }
129 +
130 + return 0;
131 +
132 +nla_put_failure:
133 + return -EMSGSIZE;
134 +}
135 +
136 /*
137 * Create one netlink message for one interface
138 * Contains port and master info as well as carrier and bridge state.
139 @@ -121,12 +233,11 @@ static int br_fill_ifinfo(struct sk_buff *skb,
140 }
141
142 /* Check if the VID information is requested */
143 - if (filter_mask & RTEXT_FILTER_BRVLAN) {
144 - struct nlattr *af;
145 + if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
146 + (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
147 const struct net_port_vlans *pv;
148 - struct bridge_vlan_info vinfo;
149 - u16 vid;
150 - u16 pvid;
151 + struct nlattr *af;
152 + int err;
153
154 if (port)
155 pv = nbp_get_vlan_info(port);
156 @@ -140,21 +251,12 @@ static int br_fill_ifinfo(struct sk_buff *skb,
157 if (!af)
158 goto nla_put_failure;
159
160 - pvid = br_get_pvid(pv);
161 - for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
162 - vinfo.vid = vid;
163 - vinfo.flags = 0;
164 - if (vid == pvid)
165 - vinfo.flags |= BRIDGE_VLAN_INFO_PVID;
166 -
167 - if (test_bit(vid, pv->untagged_bitmap))
168 - vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
169 -
170 - if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
171 - sizeof(vinfo), &vinfo))
172 - goto nla_put_failure;
173 - }
174 -
175 + if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
176 + err = br_fill_ifvlaninfo_compressed(skb, pv);
177 + else
178 + err = br_fill_ifvlaninfo(skb, pv);
179 + if (err)
180 + goto nla_put_failure;
181 nla_nest_end(skb, af);
182 }
183
184 @@ -209,7 +311,8 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
185 int err = 0;
186 struct net_bridge_port *port = br_port_get_rtnl(dev);
187
188 - if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN))
189 + if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN) &&
190 + !(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED))
191 goto out;
192
193 err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI,
194 --
195 cgit v0.10.2
196