|
1 This patch includes support for the Solaris dpif provider. |
|
2 |
|
3 This patch has not been proposed upstream because we are not yet |
|
4 proposing Solaris specific requirements upstream. |
|
5 |
|
6 diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c |
|
7 index 78f8636..d9b18d0 100644 |
|
8 --- a/lib/dpif-netdev.c |
|
9 +++ b/lib/dpif-netdev.c |
|
10 @@ -2269,6 +2269,7 @@ const struct dpif_class dpif_netdev_class = { |
|
11 dpif_netdev_recv, |
|
12 dpif_netdev_recv_wait, |
|
13 dpif_netdev_recv_purge, |
|
14 + NULL, |
|
15 }; |
|
16 |
|
17 static void |
|
18 diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h |
|
19 index 389e84e..7df0e3c 100644 |
|
20 --- a/lib/dpif-provider.h |
|
21 +++ b/lib/dpif-provider.h |
|
22 @@ -436,9 +436,13 @@ struct dpif_class { |
|
23 /* Throws away any queued upcalls that 'dpif' currently has ready to |
|
24 * return. */ |
|
25 void (*recv_purge)(struct dpif *dpif); |
|
26 + |
|
27 + /* Configure port on bridge. */ |
|
28 + int (*configure_bridge_port)(const struct dpif *, const char *devname); |
|
29 }; |
|
30 |
|
31 extern const struct dpif_class dpif_linux_class; |
|
32 +extern const struct dpif_class dpif_solaris_class; |
|
33 extern const struct dpif_class dpif_netdev_class; |
|
34 |
|
35 #ifdef __cplusplus |
|
36 diff --git a/lib/dpif.c b/lib/dpif.c |
|
37 index 450c6c8..d5a89da 100644 |
|
38 --- a/lib/dpif.c |
|
39 +++ b/lib/dpif.c |
|
40 @@ -60,6 +60,9 @@ static const struct dpif_class *base_dpif_classes[] = { |
|
41 #ifdef __linux__ |
|
42 &dpif_linux_class, |
|
43 #endif |
|
44 +#ifdef __sun |
|
45 + &dpif_solaris_class, |
|
46 +#endif |
|
47 &dpif_netdev_class, |
|
48 }; |
|
49 |
|
50 @@ -661,6 +664,14 @@ dpif_port_get_pid(const struct dpif *dpif, odp_port_t port_no, uint32_t hash) |
|
51 : 0); |
|
52 } |
|
53 |
|
54 +int |
|
55 +dpif_configure_bridge_port(const struct dpif *dpif, const char *devname) |
|
56 +{ |
|
57 + return (dpif->dpif_class->configure_bridge_port |
|
58 + ? (dpif->dpif_class->configure_bridge_port)(dpif, devname) |
|
59 + : 0); |
|
60 +} |
|
61 + |
|
62 /* Looks up port number 'port_no' in 'dpif'. On success, returns 0 and copies |
|
63 * the port's name into the 'name_size' bytes in 'name', ensuring that the |
|
64 * result is null-terminated. On failure, returns a positive errno value and |
|
65 diff --git a/lib/dpif.h b/lib/dpif.h |
|
66 index f13cc36..25b4845 100644 |
|
67 --- a/lib/dpif.h |
|
68 +++ b/lib/dpif.h |
|
69 @@ -468,6 +468,7 @@ int dpif_port_get_name(struct dpif *, odp_port_t port_no, |
|
70 char *name, size_t name_size); |
|
71 uint32_t dpif_port_get_pid(const struct dpif *, odp_port_t port_no, |
|
72 uint32_t hash); |
|
73 +int dpif_configure_bridge_port(const struct dpif *dpif, const char *devname); |
|
74 |
|
75 struct dpif_port_dump { |
|
76 const struct dpif *dpif; |
|
77 diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c |
|
78 index 46595f8..2bb200c 100644 |
|
79 --- a/ofproto/ofproto-dpif.c |
|
80 +++ b/ofproto/ofproto-dpif.c |
|
81 @@ -1431,7 +1431,7 @@ run(struct ofproto *ofproto_) |
|
82 } |
|
83 |
|
84 static void |
|
85 -wait(struct ofproto *ofproto_) |
|
86 +dpwait(struct ofproto *ofproto_) |
|
87 { |
|
88 struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); |
|
89 |
|
90 @@ -2839,6 +2839,17 @@ port_query_by_name(const struct ofproto *ofproto_, const char *devname, |
|
91 } |
|
92 |
|
93 static int |
|
94 +configure_bridge_port(const struct ofproto *ofproto_, const char *devname) |
|
95 +{ |
|
96 + struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); |
|
97 + |
|
98 + if (!sset_contains(&ofproto->ports, devname)) { |
|
99 + return ENODEV; |
|
100 + } |
|
101 + return (dpif_configure_bridge_port(ofproto->backer->dpif, devname)); |
|
102 +} |
|
103 + |
|
104 +static int |
|
105 port_add(struct ofproto *ofproto_, struct netdev *netdev) |
|
106 { |
|
107 struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); |
|
108 @@ -4867,7 +4878,7 @@ const struct ofproto_class ofproto_dpif_class = { |
|
109 destruct, |
|
110 dealloc, |
|
111 run, |
|
112 - wait, |
|
113 + dpwait, |
|
114 NULL, /* get_memory_usage. */ |
|
115 type_get_memory_usage, |
|
116 flush, |
|
117 @@ -4934,4 +4945,5 @@ const struct ofproto_class ofproto_dpif_class = { |
|
118 group_dealloc, /* group_dealloc */ |
|
119 group_modify, /* group_modify */ |
|
120 group_get_stats, /* group_get_stats */ |
|
121 + configure_bridge_port /* configure_bridge_port */ |
|
122 }; |
|
123 diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h |
|
124 index 1978a20..f743a8a 100644 |
|
125 --- a/ofproto/ofproto-provider.h |
|
126 +++ b/ofproto/ofproto-provider.h |
|
127 @@ -1695,6 +1695,8 @@ struct ofproto_class { |
|
128 |
|
129 enum ofperr (*group_get_stats)(const struct ofgroup *, |
|
130 struct ofputil_group_stats *); |
|
131 + int (*configure_bridge_port)(const struct ofproto *ofproto, |
|
132 + const char *devname); |
|
133 }; |
|
134 |
|
135 extern const struct ofproto_class ofproto_dpif_class; |
|
136 diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c |
|
137 index 2048fde..2b25fe4 100644 |
|
138 --- a/ofproto/ofproto.c |
|
139 +++ b/ofproto/ofproto.c |
|
140 @@ -1826,6 +1826,13 @@ ofproto_port_query_by_name(const struct ofproto *ofproto, const char *devname, |
|
141 return error; |
|
142 } |
|
143 |
|
144 +int |
|
145 +ofproto_configure_bridge_port(const struct ofproto *ofproto, |
|
146 + const char *devname) |
|
147 +{ |
|
148 + return (ofproto->ofproto_class->configure_bridge_port(ofproto, devname)); |
|
149 +} |
|
150 + |
|
151 /* Deletes port number 'ofp_port' from the datapath for 'ofproto'. |
|
152 * Returns 0 if successful, otherwise a positive errno. */ |
|
153 int |
|
154 diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h |
|
155 index 9a06849..94dce34 100644 |
|
156 --- a/ofproto/ofproto.h |
|
157 +++ b/ofproto/ofproto.h |
|
158 @@ -224,6 +224,7 @@ int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats); |
|
159 |
|
160 int ofproto_port_query_by_name(const struct ofproto *, const char *devname, |
|
161 struct ofproto_port *); |
|
162 +int ofproto_configure_bridge_port(const struct ofproto *, const char *); |
|
163 |
|
164 /* Top-level configuration. */ |
|
165 uint64_t ofproto_get_datapath_id(const struct ofproto *); |
|
166 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c |
|
167 index 4f77ac5..b9f1801 100644 |
|
168 --- a/ofproto/ofproto-dpif-xlate.c |
|
169 +++ b/ofproto/ofproto-dpif-xlate.c |
|
170 @@ -3184,6 +3184,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) |
|
171 ovs_rwlock_unlock(&xlate_rwlock); |
|
172 } |
|
173 |
|
174 +#ifdef __linux__ |
|
175 /* Returns the maximum number of packets that the Linux kernel is willing to |
|
176 * queue up internally to certain kinds of software-implemented ports, or the |
|
177 * default (and rarely modified) value if it cannot be determined. */ |
|
178 @@ -3236,7 +3237,9 @@ count_output_actions(const struct ofpbuf *odp_actions) |
|
179 } |
|
180 return n; |
|
181 } |
|
182 +#endif |
|
183 |
|
184 +#ifdef __linux__ |
|
185 /* Returns true if 'odp_actions' contains more output actions than the datapath |
|
186 * can reliably handle in one go. On Linux, this is the value of the |
|
187 * net.core.netdev_max_backlog sysctl, which limits the maximum number of |
|
188 @@ -3245,15 +3248,18 @@ count_output_actions(const struct ofpbuf *odp_actions) |
|
189 static bool |
|
190 too_many_output_actions(const struct ofpbuf *odp_actions) |
|
191 { |
|
192 -#ifdef __linux__ |
|
193 return (ofpbuf_size(odp_actions) / NL_A_U32_SIZE > netdev_max_backlog() |
|
194 && count_output_actions(odp_actions) > netdev_max_backlog()); |
|
195 +} |
|
196 #else |
|
197 +static bool |
|
198 +too_many_output_actions(const struct ofpbuf *odp_actions OVS_UNUSED) |
|
199 +{ |
|
200 /* OSes other than Linux might have similar limits, but we don't know how |
|
201 * to determine them.*/ |
|
202 return false; |
|
203 -#endif |
|
204 } |
|
205 +#endif |
|
206 |
|
207 /* Translates the 'ofpacts_len' bytes of "struct ofpacts" starting at 'ofpacts' |
|
208 * into datapath actions in 'odp_actions', using 'ctx'. |