]> git.proxmox.com Git - mirror_ovs.git/blame - ovn/controller/pinctrl.c
ofproto: Add ref counting for variable length mf_fields.
[mirror_ovs.git] / ovn / controller / pinctrl.c
CommitLineData
f9c83246 1/* Copyright (c) 2015, 2016 Red Hat, Inc.
04f48a68 2 * Copyright (c) 2017 Nicira, Inc.
27732ac4
BS
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <config.h>
6335d074 18
27732ac4 19#include "pinctrl.h"
6335d074 20
0bac7164 21#include "coverage.h"
42814145 22#include "csum.h"
6335d074
BP
23#include "dirs.h"
24#include "dp-packet.h"
f4248336 25#include "flow.h"
0bac7164 26#include "lport.h"
42814145 27#include "nx-match.h"
0ee8aaf6 28#include "ovn-controller.h"
e75451fe 29#include "lib/packets.h"
0ee8aaf6 30#include "lib/sset.h"
b598f214 31#include "openvswitch/ofp-actions.h"
d271907f 32#include "openvswitch/ofp-msgs.h"
25d436fb 33#include "openvswitch/ofp-print.h"
f4248336 34#include "openvswitch/ofp-util.h"
27732ac4 35#include "openvswitch/vlog.h"
42814145
NS
36
37#include "lib/dhcp.h"
0bac7164 38#include "ovn-controller.h"
8b2ed684 39#include "ovn/actions.h"
d271907f 40#include "ovn/lib/logical-fields.h"
01cfdb2f 41#include "ovn/lib/ovn-dhcp.h"
0ee8aaf6 42#include "ovn/lib/ovn-util.h"
0bac7164 43#include "poll-loop.h"
d271907f 44#include "rconn.h"
27732ac4 45#include "socket-util.h"
0bac7164 46#include "timeval.h"
27732ac4
BS
47#include "vswitch-idl.h"
48
49VLOG_DEFINE_THIS_MODULE(pinctrl);
50
51/* OpenFlow connection to the switch. */
52static struct rconn *swconn;
53
54/* Last seen sequence number for 'swconn'. When this differs from
55 * rconn_get_connection_seqno(rconn), 'swconn' has reconnected. */
56static unsigned int conn_seq_no;
57
c34a87b6
JP
58static void pinctrl_handle_put_mac_binding(const struct flow *md,
59 const struct flow *headers,
60 bool is_arp);
61static void init_put_mac_bindings(void);
62static void destroy_put_mac_bindings(void);
63static void run_put_mac_bindings(struct controller_ctx *,
64 const struct lport_index *lports);
65static void wait_put_mac_bindings(struct controller_ctx *);
66static void flush_put_mac_bindings(void);
0bac7164 67
0ee8aaf6
RR
68static void init_send_garps(void);
69static void destroy_send_garps(void);
70static void send_garp_wait(void);
71static void send_garp_run(const struct ovsrec_bridge *,
f1a8bd06 72 const struct sbrec_chassis *,
0ee8aaf6
RR
73 const struct lport_index *lports,
74 struct hmap *local_datapaths);
f8a8db39
JP
75static void pinctrl_handle_nd_na(const struct flow *ip_flow,
76 const struct match *md,
77 struct ofpbuf *userdata);
e75451fe
ZKL
78static void reload_metadata(struct ofpbuf *ofpacts,
79 const struct match *md);
0ee8aaf6 80
c34a87b6 81COVERAGE_DEFINE(pinctrl_drop_put_mac_binding);
0bac7164 82
27732ac4
BS
83void
84pinctrl_init(void)
85{
86 swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
87 conn_seq_no = 0;
c34a87b6 88 init_put_mac_bindings();
0ee8aaf6 89 init_send_garps();
27732ac4
BS
90}
91
92static ovs_be32
93queue_msg(struct ofpbuf *msg)
94{
95 const struct ofp_header *oh = msg->data;
96 ovs_be32 xid = oh->xid;
97
98 rconn_send(swconn, msg, NULL);
99 return xid;
100}
101
6335d074 102/* Sets up 'swconn', a newly (re)connected connection to a switch. */
27732ac4 103static void
6335d074 104pinctrl_setup(struct rconn *swconn)
27732ac4 105{
6335d074
BP
106 /* Fetch the switch configuration. The response later will allow us to
107 * change the miss_send_len to UINT16_MAX, so that we can enable
108 * asynchronous messages. */
109 queue_msg(ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST,
110 rconn_get_version(swconn), 0));
27732ac4 111
6335d074
BP
112 /* Set a packet-in format that supports userdata. */
113 queue_msg(ofputil_make_set_packet_in_format(rconn_get_version(swconn),
114 NXPIF_NXT_PACKET_IN2));
27732ac4
BS
115}
116
117static void
660f5a61
NS
118set_switch_config(struct rconn *swconn,
119 const struct ofputil_switch_config *config)
27732ac4 120{
660f5a61
NS
121 enum ofp_version version = rconn_get_version(swconn);
122 struct ofpbuf *request = ofputil_encode_set_config(config, version);
27732ac4
BS
123 queue_msg(request);
124}
125
126static void
0bac7164
BP
127pinctrl_handle_arp(const struct flow *ip_flow, const struct match *md,
128 struct ofpbuf *userdata)
27732ac4 129{
6335d074
BP
130 /* This action only works for IP packets, and the switch should only send
131 * us IP packets this way, but check here just to be sure. */
132 if (ip_flow->dl_type != htons(ETH_TYPE_IP)) {
133 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
134 VLOG_WARN_RL(&rl, "ARP action on non-IP packet (Ethertype %"PRIx16")",
135 ntohs(ip_flow->dl_type));
136 return;
137 }
138
139 /* Compose an ARP packet. */
140 uint64_t packet_stub[128 / 8];
141 struct dp_packet packet;
142 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
143 compose_arp__(&packet);
144
145 struct eth_header *eth = dp_packet_l2(&packet);
146 eth->eth_dst = ip_flow->dl_dst;
147 eth->eth_src = ip_flow->dl_src;
148
149 struct arp_eth_header *arp = dp_packet_l3(&packet);
150 arp->ar_op = htons(ARP_OP_REQUEST);
151 arp->ar_sha = ip_flow->dl_src;
152 put_16aligned_be32(&arp->ar_spa, ip_flow->nw_src);
153 arp->ar_tha = eth_addr_zero;
154 put_16aligned_be32(&arp->ar_tpa, ip_flow->nw_dst);
155
156 if (ip_flow->vlan_tci & htons(VLAN_CFI)) {
157 eth_push_vlan(&packet, htons(ETH_TYPE_VLAN_8021Q), ip_flow->vlan_tci);
158 }
159
160 /* Compose actions.
161 *
0bac7164
BP
162 * First, copy metadata from 'md' into the packet-out via "set_field"
163 * actions, then add actions from 'userdata'.
6335d074 164 */
0bac7164 165 uint64_t ofpacts_stub[4096 / 8];
6335d074
BP
166 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
167 enum ofp_version version = rconn_get_version(swconn);
168
e75451fe 169 reload_metadata(&ofpacts, md);
04f48a68 170 enum ofperr error = ofpacts_pull_openflow_actions(userdata, userdata->size,
5c7c16d8
YHW
171 version, NULL, NULL,
172 &ofpacts);
6335d074
BP
173 if (error) {
174 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
175 VLOG_WARN_RL(&rl, "failed to parse arp actions (%s)",
176 ofperr_to_string(error));
177 goto exit;
178 }
179
180 struct ofputil_packet_out po = {
181 .packet = dp_packet_data(&packet),
182 .packet_len = dp_packet_size(&packet),
183 .buffer_id = UINT32_MAX,
184 .in_port = OFPP_CONTROLLER,
185 .ofpacts = ofpacts.data,
186 .ofpacts_len = ofpacts.size,
187 };
188 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
189 queue_msg(ofputil_encode_packet_out(&po, proto));
27732ac4 190
6335d074
BP
191exit:
192 dp_packet_uninit(&packet);
193 ofpbuf_uninit(&ofpacts);
194}
195
42814145
NS
196static void
197pinctrl_handle_put_dhcp_opts(
198 struct dp_packet *pkt_in, struct ofputil_packet_in *pin,
199 struct ofpbuf *userdata, struct ofpbuf *continuation)
200{
201 enum ofp_version version = rconn_get_version(swconn);
202 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
203 struct dp_packet *pkt_out_ptr = NULL;
204 uint32_t success = 0;
205
206 /* Parse result field. */
207 const struct mf_field *f;
04f48a68 208 enum ofperr ofperr = nx_pull_header(userdata, NULL, &f, NULL);
42814145
NS
209 if (ofperr) {
210 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
211 VLOG_WARN_RL(&rl, "bad result OXM (%s)", ofperr_to_string(ofperr));
212 goto exit;
213 }
214
215 /* Parse result offset and offer IP. */
216 ovs_be32 *ofsp = ofpbuf_try_pull(userdata, sizeof *ofsp);
217 ovs_be32 *offer_ip = ofpbuf_try_pull(userdata, sizeof *offer_ip);
218 if (!ofsp || !offer_ip) {
219 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
220 VLOG_WARN_RL(&rl, "offset or offer_ip not present in the userdata");
221 goto exit;
222 }
223
224 /* Check that the result is valid and writable. */
225 struct mf_subfield dst = { .field = f, .ofs = ntohl(*ofsp), .n_bits = 1 };
226 ofperr = mf_check_dst(&dst, NULL);
227 if (ofperr) {
228 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
229 VLOG_WARN_RL(&rl, "bad result bit (%s)", ofperr_to_string(ofperr));
230 goto exit;
231 }
232
233 if (!userdata->size) {
234 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
235 VLOG_WARN_RL(&rl, "DHCP options not present in the userdata");
236 goto exit;
237 }
238
239 /* Validate the DHCP request packet.
240 * Format of the DHCP packet is
241 * ------------------------------------------------------------------------
242 *| UDP HEADER | DHCP HEADER | 4 Byte DHCP Cookie | DHCP OPTIONS(var len)|
243 * ------------------------------------------------------------------------
244 */
245 if (dp_packet_l4_size(pkt_in) < (UDP_HEADER_LEN +
246 sizeof (struct dhcp_header) + sizeof(uint32_t) + 3)) {
247 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
248 VLOG_WARN_RL(&rl, "Invalid or incomplete DHCP packet recieved");
249 goto exit;
250 }
251
252 struct dhcp_header const *in_dhcp_data = dp_packet_get_udp_payload(pkt_in);
253 if (in_dhcp_data->op != DHCP_OP_REQUEST) {
254 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
255 VLOG_WARN_RL(&rl, "Invalid opcode in the DHCP packet : %d",
256 in_dhcp_data->op);
257 goto exit;
258 }
259
260 /* DHCP options follow the DHCP header. The first 4 bytes of the DHCP
261 * options is the DHCP magic cookie followed by the actual DHCP options.
262 */
263 const uint8_t *in_dhcp_opt =
264 (const uint8_t *)dp_packet_get_udp_payload(pkt_in) +
265 sizeof (struct dhcp_header);
266
267 ovs_be32 magic_cookie = htonl(DHCP_MAGIC_COOKIE);
268 if (memcmp(in_dhcp_opt, &magic_cookie, sizeof(ovs_be32))) {
269 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
270 VLOG_WARN_RL(&rl, "DHCP magic cookie not present in the DHCP packet");
271 goto exit;
272 }
273
274 in_dhcp_opt += 4;
275 /* Check that the DHCP Message Type (opt 53) is present or not with
276 * valid values - DHCP_MSG_DISCOVER or DHCP_MSG_REQUEST as the first
277 * DHCP option.
278 */
279 if (!(in_dhcp_opt[0] == DHCP_OPT_MSG_TYPE && in_dhcp_opt[1] == 1 && (
280 in_dhcp_opt[2] == DHCP_MSG_DISCOVER ||
281 in_dhcp_opt[2] == DHCP_MSG_REQUEST))) {
282 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
283 VLOG_WARN_RL(&rl, "Invalid DHCP message type : opt code = %d,"
284 " opt value = %d", in_dhcp_opt[0], in_dhcp_opt[2]);
285 goto exit;
286 }
287
288 uint8_t msg_type;
289 if (in_dhcp_opt[2] == DHCP_MSG_DISCOVER) {
290 msg_type = DHCP_MSG_OFFER;
291 } else {
292 msg_type = DHCP_MSG_ACK;
293 }
294
295 /* Frame the DHCP reply packet
296 * Total DHCP options length will be options stored in the userdata +
297 * 16 bytes.
298 *
299 * --------------------------------------------------------------
300 *| 4 Bytes (dhcp cookie) | 3 Bytes (option type) | DHCP options |
301 * --------------------------------------------------------------
302 *| 4 Bytes padding | 1 Byte (option end 0xFF ) | 4 Bytes padding|
303 * --------------------------------------------------------------
304 */
305 uint16_t new_l4_size = UDP_HEADER_LEN + DHCP_HEADER_LEN + \
306 userdata->size + 16;
307 size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
308
309 struct dp_packet pkt_out;
310 dp_packet_init(&pkt_out, new_packet_size);
311 dp_packet_clear(&pkt_out);
312 dp_packet_prealloc_tailroom(&pkt_out, new_packet_size);
313 pkt_out_ptr = &pkt_out;
314
315 /* Copy the L2 and L3 headers from the pkt_in as they would remain same*/
316 dp_packet_put(
317 &pkt_out, dp_packet_pull(pkt_in, pkt_in->l4_ofs), pkt_in->l4_ofs);
318
319 pkt_out.l2_5_ofs = pkt_in->l2_5_ofs;
320 pkt_out.l2_pad_size = pkt_in->l2_pad_size;
321 pkt_out.l3_ofs = pkt_in->l3_ofs;
322 pkt_out.l4_ofs = pkt_in->l4_ofs;
323
324 struct udp_header *udp = dp_packet_put(
325 &pkt_out, dp_packet_pull(pkt_in, UDP_HEADER_LEN), UDP_HEADER_LEN);
326
327 struct dhcp_header *dhcp_data = dp_packet_put(
328 &pkt_out, dp_packet_pull(pkt_in, DHCP_HEADER_LEN), DHCP_HEADER_LEN);
329 dhcp_data->op = DHCP_OP_REPLY;
330 dhcp_data->yiaddr = *offer_ip;
331 dp_packet_put(&pkt_out, &magic_cookie, sizeof(ovs_be32));
332
333 uint8_t *out_dhcp_opts = dp_packet_put_zeros(&pkt_out,
334 userdata->size + 12);
335 /* DHCP option - type */
336 out_dhcp_opts[0] = DHCP_OPT_MSG_TYPE;
337 out_dhcp_opts[1] = 1;
338 out_dhcp_opts[2] = msg_type;
339 out_dhcp_opts += 3;
340
341 memcpy(out_dhcp_opts, userdata->data, userdata->size);
342 out_dhcp_opts += userdata->size;
343 /* Padding */
344 out_dhcp_opts += 4;
345 /* End */
346 out_dhcp_opts[0] = DHCP_OPT_END;
347
348 udp->udp_len = htons(new_l4_size);
349
350 struct ip_header *out_ip = dp_packet_l3(&pkt_out);
351 out_ip->ip_tot_len = htons(pkt_out.l4_ofs - pkt_out.l3_ofs + new_l4_size);
352 udp->udp_csum = 0;
ece9c294 353 /* Checksum needs to be initialized to zero. */
42814145
NS
354 out_ip->ip_csum = 0;
355 out_ip->ip_csum = csum(out_ip, sizeof *out_ip);
356
357 pin->packet = dp_packet_data(&pkt_out);
358 pin->packet_len = dp_packet_size(&pkt_out);
359
9240e9ab
RR
360 /* Log the response. */
361 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(20, 40);
362 const struct eth_header *l2 = dp_packet_l2(&pkt_out);
363 VLOG_INFO_RL(&rl, "DHCP%s "ETH_ADDR_FMT" "IP_FMT"",
364 msg_type == DHCP_MSG_OFFER ? "OFFER" : "ACK",
365 ETH_ADDR_ARGS(l2->eth_src), IP_ARGS(*offer_ip));
366
42814145
NS
367 success = 1;
368exit:
369 if (!ofperr) {
370 union mf_subvalue sv;
371 sv.u8_val = success;
372 mf_write_subfield(&dst, &sv, &pin->flow_metadata);
373 }
374 queue_msg(ofputil_encode_resume(pin, continuation, proto));
375 if (pkt_out_ptr) {
376 dp_packet_uninit(pkt_out_ptr);
377 }
378}
379
01cfdb2f
NS
380static bool
381compose_out_dhcpv6_opts(struct ofpbuf *userdata,
382 struct ofpbuf *out_dhcpv6_opts, ovs_be32 iaid)
383{
384 while (userdata->size) {
385 struct dhcp_opt6_header *userdata_opt = ofpbuf_try_pull(
386 userdata, sizeof *userdata_opt);
387 if (!userdata_opt) {
388 return false;
389 }
390
a55dacac
DDP
391 size_t size = ntohs(userdata_opt->size);
392 uint8_t *userdata_opt_data = ofpbuf_try_pull(userdata, size);
01cfdb2f
NS
393 if (!userdata_opt_data) {
394 return false;
395 }
396
a55dacac 397 switch (ntohs(userdata_opt->opt_code)) {
01cfdb2f
NS
398 case DHCPV6_OPT_SERVER_ID_CODE:
399 {
400 /* The Server Identifier option carries a DUID
401 * identifying a server between a client and a server.
402 * See RFC 3315 Sec 9 and Sec 22.3.
403 *
404 * We use DUID Based on Link-layer Address [DUID-LL].
405 */
406
407 struct dhcpv6_opt_server_id *opt_server_id = ofpbuf_put_zeros(
408 out_dhcpv6_opts, sizeof *opt_server_id);
409
410 opt_server_id->opt.code = htons(DHCPV6_OPT_SERVER_ID_CODE);
a55dacac 411 opt_server_id->opt.len = htons(size + 4);
01cfdb2f
NS
412 opt_server_id->duid_type = htons(DHCPV6_DUID_LL);
413 opt_server_id->hw_type = htons(DHCPV6_HW_TYPE_ETH);
414 memcpy(&opt_server_id->mac, userdata_opt_data,
415 sizeof(struct eth_addr));
416 break;
417 }
418
419 case DHCPV6_OPT_IA_ADDR_CODE:
420 {
a55dacac 421 if (size != sizeof(struct in6_addr)) {
01cfdb2f
NS
422 return false;
423 }
424
425 /* IA Address option is used to specify IPv6 addresses associated
426 * with an IA_NA or IA_TA. The IA Address option must be
427 * encapsulated in the Options field of an IA_NA or IA_TA option.
428 *
429 * We will encapsulate the IA Address within the IA_NA option.
430 * Please see RFC 3315 section 22.5 and 22.6
431 */
432 struct dhcpv6_opt_ia_na *opt_ia_na = ofpbuf_put_zeros(
433 out_dhcpv6_opts, sizeof *opt_ia_na);
434 opt_ia_na->opt.code = htons(DHCPV6_OPT_IA_NA_CODE);
435 /* IA_NA length (in bytes)-
436 * IAID - 4
437 * T1 - 4
438 * T2 - 4
439 * IA Address - sizeof(struct dhcpv6_opt_ia_addr)
440 */
441 opt_ia_na->opt.len = htons(12 + sizeof(struct dhcpv6_opt_ia_addr));
442 opt_ia_na->iaid = iaid;
443 /* Set the lifetime of the address(es) to infinity */
444 opt_ia_na->t1 = OVS_BE32_MAX;
445 opt_ia_na->t2 = OVS_BE32_MAX;
446
447 struct dhcpv6_opt_ia_addr *opt_ia_addr = ofpbuf_put_zeros(
448 out_dhcpv6_opts, sizeof *opt_ia_addr);
449 opt_ia_addr->opt.code = htons(DHCPV6_OPT_IA_ADDR_CODE);
a55dacac
DDP
450 opt_ia_addr->opt.len = htons(size + 8);
451 memcpy(opt_ia_addr->ipv6.s6_addr, userdata_opt_data, size);
01cfdb2f
NS
452 opt_ia_addr->t1 = OVS_BE32_MAX;
453 opt_ia_addr->t2 = OVS_BE32_MAX;
454 break;
455 }
456
457 case DHCPV6_OPT_DNS_SERVER_CODE:
458 {
459 struct dhcpv6_opt_header *opt_dns = ofpbuf_put_zeros(
460 out_dhcpv6_opts, sizeof *opt_dns);
461 opt_dns->code = htons(DHCPV6_OPT_DNS_SERVER_CODE);
a55dacac
DDP
462 opt_dns->len = htons(size);
463 ofpbuf_put(out_dhcpv6_opts, userdata_opt_data, size);
01cfdb2f
NS
464 break;
465 }
466
467 case DHCPV6_OPT_DOMAIN_SEARCH_CODE:
468 {
469 struct dhcpv6_opt_header *opt_dsl = ofpbuf_put_zeros(
470 out_dhcpv6_opts, sizeof *opt_dsl);
471 opt_dsl->code = htons(DHCPV6_OPT_DOMAIN_SEARCH_CODE);
a55dacac
DDP
472 opt_dsl->len = htons(size + 2);
473 uint8_t *data = ofpbuf_put_zeros(out_dhcpv6_opts, size + 2);
474 *data = size;
475 memcpy(data + 1, userdata_opt_data, size);
01cfdb2f
NS
476 break;
477 }
478
479 default:
480 return false;
481 }
482 }
483 return true;
484}
485
486static void
487pinctrl_handle_put_dhcpv6_opts(
488 struct dp_packet *pkt_in, struct ofputil_packet_in *pin,
489 struct ofpbuf *userdata, struct ofpbuf *continuation OVS_UNUSED)
490{
491 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
492 enum ofp_version version = rconn_get_version(swconn);
493 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
494 struct dp_packet *pkt_out_ptr = NULL;
495 uint32_t success = 0;
496
497 /* Parse result field. */
498 const struct mf_field *f;
04f48a68 499 enum ofperr ofperr = nx_pull_header(userdata, NULL, &f, NULL);
01cfdb2f
NS
500 if (ofperr) {
501 VLOG_WARN_RL(&rl, "bad result OXM (%s)", ofperr_to_string(ofperr));
502 goto exit;
503 }
504
505 /* Parse result offset. */
506 ovs_be32 *ofsp = ofpbuf_try_pull(userdata, sizeof *ofsp);
507 if (!ofsp) {
508 VLOG_WARN_RL(&rl, "offset not present in the userdata");
509 goto exit;
510 }
511
512 /* Check that the result is valid and writable. */
513 struct mf_subfield dst = { .field = f, .ofs = ntohl(*ofsp), .n_bits = 1 };
514 ofperr = mf_check_dst(&dst, NULL);
515 if (ofperr) {
516 VLOG_WARN_RL(&rl, "bad result bit (%s)", ofperr_to_string(ofperr));
517 goto exit;
518 }
519
520 if (!userdata->size) {
521 VLOG_WARN_RL(&rl, "DHCPv6 options not present in the userdata");
522 goto exit;
523 }
524
525 struct udp_header *in_udp = dp_packet_l4(pkt_in);
526 const uint8_t *in_dhcpv6_data = dp_packet_get_udp_payload(pkt_in);
527 uint8_t out_dhcpv6_msg_type;
528 switch(*in_dhcpv6_data) {
529 case DHCPV6_MSG_TYPE_SOLICIT:
530 out_dhcpv6_msg_type = DHCPV6_MSG_TYPE_ADVT;
531 break;
532
533 case DHCPV6_MSG_TYPE_REQUEST:
534 case DHCPV6_MSG_TYPE_CONFIRM:
535 case DHCPV6_MSG_TYPE_DECLINE:
536 out_dhcpv6_msg_type = DHCPV6_MSG_TYPE_REPLY;
537 break;
538
539 default:
540 /* Invalid or unsupported DHCPv6 message type */
541 goto exit;
542 }
543
544 /* Skip 4 bytes (message type (1 byte) + transaction ID (3 bytes). */
545 in_dhcpv6_data += 4;
546 /* We need to extract IAID from the IA-NA option of the client's DHCPv6
547 * solicit/request/confirm packet and copy the same IAID in the Server's
548 * response. */
549 ovs_be32 iaid = 0;
550 struct dhcpv6_opt_header const *in_opt_client_id = NULL;
551 size_t udp_len = ntohs(in_udp->udp_len);
552 size_t l4_len = dp_packet_l4_size(pkt_in);
553 uint8_t *end = (uint8_t *)in_udp + MIN(udp_len, l4_len);
554 while (in_dhcpv6_data < end) {
555 struct dhcpv6_opt_header const *in_opt =
556 (struct dhcpv6_opt_header *)in_dhcpv6_data;
557 switch(ntohs(in_opt->code)) {
558 case DHCPV6_OPT_IA_NA_CODE:
559 {
560 struct dhcpv6_opt_ia_na *opt_ia_na = (
561 struct dhcpv6_opt_ia_na *)in_opt;
562 iaid = opt_ia_na->iaid;
563 break;
564 }
565
566 case DHCPV6_OPT_CLIENT_ID_CODE:
567 in_opt_client_id = in_opt;
568 break;
569
570 default:
571 break;
572 }
573 in_dhcpv6_data += sizeof *in_opt + ntohs(in_opt->len);
574 }
575
576 if (!in_opt_client_id) {
577 VLOG_WARN_RL(&rl, "DHCPv6 option - Client id not present in the "
578 " DHCPv6 packet");
579 goto exit;
580 }
581
582 if (!iaid) {
583 VLOG_WARN_RL(&rl, "DHCPv6 option - IA NA not present in the "
584 " DHCPv6 packet");
585 goto exit;
586 }
587
588 uint64_t out_ofpacts_dhcpv6_opts_stub[256 / 8];
589 struct ofpbuf out_dhcpv6_opts =
590 OFPBUF_STUB_INITIALIZER(out_ofpacts_dhcpv6_opts_stub);
591
592 if (!compose_out_dhcpv6_opts(userdata, &out_dhcpv6_opts, iaid)) {
593 VLOG_WARN_RL(&rl, "Invalid userdata");
594 goto exit;
595 }
596
597 uint16_t new_l4_size
598 = (UDP_HEADER_LEN + 4 + sizeof *in_opt_client_id +
599 ntohs(in_opt_client_id->len) + out_dhcpv6_opts.size);
600 size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
601
602 struct dp_packet pkt_out;
603 dp_packet_init(&pkt_out, new_packet_size);
604 dp_packet_clear(&pkt_out);
605 dp_packet_prealloc_tailroom(&pkt_out, new_packet_size);
606 pkt_out_ptr = &pkt_out;
607
608 /* Copy L2 and L3 headers from pkt_in. */
609 dp_packet_put(&pkt_out, dp_packet_pull(pkt_in, pkt_in->l4_ofs),
610 pkt_in->l4_ofs);
611
612 pkt_out.l2_5_ofs = pkt_in->l2_5_ofs;
613 pkt_out.l2_pad_size = pkt_in->l2_pad_size;
614 pkt_out.l3_ofs = pkt_in->l3_ofs;
615 pkt_out.l4_ofs = pkt_in->l4_ofs;
616
617 /* Pull the DHCPv6 message type and transaction id from the pkt_in.
618 * Need to preserve the transaction id in the DHCPv6 reply packet. */
619 struct udp_header *out_udp = dp_packet_put(
620 &pkt_out, dp_packet_pull(pkt_in, UDP_HEADER_LEN), UDP_HEADER_LEN);
621 uint8_t *out_dhcpv6 = dp_packet_put(&pkt_out, dp_packet_pull(pkt_in, 4), 4);
622
623 /* Set the proper DHCPv6 message type. */
624 *out_dhcpv6 = out_dhcpv6_msg_type;
625
626 /* Copy the Client Identifier. */
627 dp_packet_put(&pkt_out, in_opt_client_id,
628 sizeof *in_opt_client_id + ntohs(in_opt_client_id->len));
629
630 /* Copy the DHCPv6 Options. */
631 dp_packet_put(&pkt_out, out_dhcpv6_opts.data, out_dhcpv6_opts.size);
632 out_udp->udp_len = htons(new_l4_size);
633 out_udp->udp_csum = 0;
634
635 struct ovs_16aligned_ip6_hdr *out_ip6 = dp_packet_l3(&pkt_out);
636 out_ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = out_udp->udp_len;
637
638 uint32_t csum;
639 csum = packet_csum_pseudoheader6(dp_packet_l3(&pkt_out));
640 csum = csum_continue(csum, out_udp, dp_packet_size(&pkt_out) -
641 ((const unsigned char *)out_udp -
642 (const unsigned char *)dp_packet_l2(&pkt_out)));
643 out_udp->udp_csum = csum_finish(csum);
644 if (!out_udp->udp_csum) {
645 out_udp->udp_csum = htons(0xffff);
646 }
647
648 pin->packet = dp_packet_data(&pkt_out);
649 pin->packet_len = dp_packet_size(&pkt_out);
650 ofpbuf_uninit(&out_dhcpv6_opts);
651 success = 1;
652exit:
653 if (!ofperr) {
654 union mf_subvalue sv;
655 sv.u8_val = success;
656 mf_write_subfield(&dst, &sv, &pin->flow_metadata);
657 }
658 queue_msg(ofputil_encode_resume(pin, continuation, proto));
659 dp_packet_uninit(pkt_out_ptr);
660}
661
6335d074
BP
662static void
663process_packet_in(const struct ofp_header *msg)
664{
665 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
666
667 struct ofputil_packet_in pin;
42814145 668 struct ofpbuf continuation;
3cddeff0 669 enum ofperr error = ofputil_decode_packet_in(msg, true, NULL, NULL, &pin,
42814145
NS
670 NULL, NULL, &continuation);
671
6335d074
BP
672 if (error) {
673 VLOG_WARN_RL(&rl, "error decoding packet-in: %s",
674 ofperr_to_string(error));
27732ac4
BS
675 return;
676 }
677 if (pin.reason != OFPR_ACTION) {
678 return;
679 }
680
6335d074
BP
681 struct ofpbuf userdata = ofpbuf_const_initializer(pin.userdata,
682 pin.userdata_len);
683 const struct action_header *ah = ofpbuf_pull(&userdata, sizeof *ah);
684 if (!ah) {
685 VLOG_WARN_RL(&rl, "packet-in userdata lacks action header");
686 return;
687 }
688
689 struct dp_packet packet;
690 dp_packet_use_const(&packet, pin.packet, pin.packet_len);
691 struct flow headers;
692 flow_extract(&packet, &headers);
693
6335d074
BP
694 switch (ntohl(ah->opcode)) {
695 case ACTION_OPCODE_ARP:
0bac7164
BP
696 pinctrl_handle_arp(&headers, &pin.flow_metadata, &userdata);
697 break;
698
699 case ACTION_OPCODE_PUT_ARP:
c34a87b6
JP
700 pinctrl_handle_put_mac_binding(&pin.flow_metadata.flow, &headers,
701 true);
6335d074
BP
702 break;
703
42814145
NS
704 case ACTION_OPCODE_PUT_DHCP_OPTS:
705 pinctrl_handle_put_dhcp_opts(&packet, &pin, &userdata, &continuation);
706 break;
707
f8a8db39
JP
708 case ACTION_OPCODE_ND_NA:
709 pinctrl_handle_nd_na(&headers, &pin.flow_metadata, &userdata);
e75451fe
ZKL
710 break;
711
c34a87b6
JP
712 case ACTION_OPCODE_PUT_ND:
713 pinctrl_handle_put_mac_binding(&pin.flow_metadata.flow, &headers,
714 false);
715 break;
716
01cfdb2f
NS
717 case ACTION_OPCODE_PUT_DHCPV6_OPTS:
718 pinctrl_handle_put_dhcpv6_opts(&packet, &pin, &userdata,
719 &continuation);
720 break;
721
6335d074 722 default:
0bac7164
BP
723 VLOG_WARN_RL(&rl, "unrecognized packet-in opcode %"PRIu32,
724 ntohl(ah->opcode));
6335d074
BP
725 break;
726 }
27732ac4
BS
727}
728
729static void
6335d074 730pinctrl_recv(const struct ofp_header *oh, enum ofptype type)
27732ac4
BS
731{
732 if (type == OFPTYPE_ECHO_REQUEST) {
733 queue_msg(make_echo_reply(oh));
734 } else if (type == OFPTYPE_GET_CONFIG_REPLY) {
7c9afefd 735 /* Enable asynchronous messages */
660f5a61 736 struct ofputil_switch_config config;
27732ac4 737
660f5a61 738 ofputil_decode_get_config_reply(oh, &config);
3ca6cc76 739 config.miss_send_len = UINT16_MAX;
27732ac4
BS
740 set_switch_config(swconn, &config);
741 } else if (type == OFPTYPE_PACKET_IN) {
6335d074 742 process_packet_in(oh);
27732ac4
BS
743 } else if (type != OFPTYPE_ECHO_REPLY && type != OFPTYPE_BARRIER_REPLY) {
744 if (VLOG_IS_DBG_ENABLED()) {
745 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
746
747 char *s = ofp_to_string(oh, ntohs(oh->length), 2);
748
749 VLOG_DBG_RL(&rl, "OpenFlow packet ignored: %s", s);
750 free(s);
751 }
752 }
753}
754
755void
0bac7164 756pinctrl_run(struct controller_ctx *ctx, const struct lport_index *lports,
0ee8aaf6 757 const struct ovsrec_bridge *br_int,
f1a8bd06 758 const struct sbrec_chassis *chassis,
0ee8aaf6 759 struct hmap *local_datapaths)
27732ac4 760{
3d0b8206 761 char *target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
762 if (strcmp(target, rconn_get_target(swconn))) {
763 VLOG_INFO("%s: connecting to switch", target);
764 rconn_connect(swconn, target, target);
27732ac4 765 }
3d0b8206 766 free(target);
27732ac4
BS
767
768 rconn_run(swconn);
769
6335d074
BP
770 if (rconn_is_connected(swconn)) {
771 if (conn_seq_no != rconn_get_connection_seqno(swconn)) {
772 pinctrl_setup(swconn);
773 conn_seq_no = rconn_get_connection_seqno(swconn);
c34a87b6 774 flush_put_mac_bindings();
6335d074 775 }
27732ac4 776
6335d074
BP
777 /* Process a limited number of messages per call. */
778 for (int i = 0; i < 50; i++) {
779 struct ofpbuf *msg = rconn_recv(swconn);
780 if (!msg) {
781 break;
782 }
27732ac4 783
6335d074
BP
784 const struct ofp_header *oh = msg->data;
785 enum ofptype type;
27732ac4 786
6335d074
BP
787 ofptype_decode(&type, oh);
788 pinctrl_recv(oh, type);
789 ofpbuf_delete(msg);
790 }
27732ac4 791 }
0bac7164 792
c34a87b6 793 run_put_mac_bindings(ctx, lports);
f1a8bd06 794 send_garp_run(br_int, chassis, lports, local_datapaths);
27732ac4
BS
795}
796
797void
0bac7164 798pinctrl_wait(struct controller_ctx *ctx)
27732ac4 799{
c34a87b6 800 wait_put_mac_bindings(ctx);
27732ac4
BS
801 rconn_run_wait(swconn);
802 rconn_recv_wait(swconn);
0ee8aaf6 803 send_garp_wait();
27732ac4
BS
804}
805
806void
807pinctrl_destroy(void)
808{
809 rconn_destroy(swconn);
c34a87b6 810 destroy_put_mac_bindings();
0ee8aaf6 811 destroy_send_garps();
0bac7164
BP
812}
813\f
c34a87b6
JP
814/* Implementation of the "put_arp" and "put_nd" OVN actions. These
815 * actions send a packet to ovn-controller, using the flow as an API
816 * (see actions.h for details). This code implements the actions by
817 * updating the MAC_Binding table in the southbound database.
0bac7164
BP
818 *
819 * This code could be a lot simpler if the database could always be updated,
820 * but in fact we can only update it when ctx->ovnsb_idl_txn is nonnull. Thus,
c34a87b6
JP
821 * we buffer up a few put_mac_bindings (but we don't keep them longer
822 * than 1 second) and apply them whenever a database transaction is
823 * available. */
0bac7164 824
c34a87b6
JP
825/* Buffered "put_mac_binding" operation. */
826struct put_mac_binding {
827 struct hmap_node hmap_node; /* In 'put_mac_bindings'. */
0bac7164
BP
828
829 long long int timestamp; /* In milliseconds. */
830
831 /* Key. */
832 uint32_t dp_key;
833 uint32_t port_key;
c34a87b6 834 char ip_s[INET6_ADDRSTRLEN + 1];
0bac7164
BP
835
836 /* Value. */
837 struct eth_addr mac;
838};
839
c34a87b6
JP
840/* Contains "struct put_mac_binding"s. */
841static struct hmap put_mac_bindings;
0bac7164
BP
842
843static void
c34a87b6 844init_put_mac_bindings(void)
0bac7164 845{
c34a87b6 846 hmap_init(&put_mac_bindings);
0bac7164
BP
847}
848
849static void
c34a87b6 850destroy_put_mac_bindings(void)
0bac7164 851{
c34a87b6
JP
852 flush_put_mac_bindings();
853 hmap_destroy(&put_mac_bindings);
0bac7164
BP
854}
855
c34a87b6
JP
856static struct put_mac_binding *
857pinctrl_find_put_mac_binding(uint32_t dp_key, uint32_t port_key,
858 const char *ip_s, uint32_t hash)
0bac7164 859{
c34a87b6
JP
860 struct put_mac_binding *pa;
861 HMAP_FOR_EACH_WITH_HASH (pa, hmap_node, hash, &put_mac_bindings) {
0bac7164
BP
862 if (pa->dp_key == dp_key
863 && pa->port_key == port_key
c34a87b6 864 && !strcmp(pa->ip_s, ip_s)) {
0bac7164
BP
865 return pa;
866 }
867 }
868 return NULL;
869}
870
871static void
c34a87b6
JP
872pinctrl_handle_put_mac_binding(const struct flow *md,
873 const struct flow *headers, bool is_arp)
0bac7164
BP
874{
875 uint32_t dp_key = ntohll(md->metadata);
876 uint32_t port_key = md->regs[MFF_LOG_INPORT - MFF_REG0];
c34a87b6
JP
877 char ip_s[INET6_ADDRSTRLEN];
878
879 if (is_arp) {
880 ovs_be32 ip = htonl(md->regs[0]);
881 inet_ntop(AF_INET, &ip, ip_s, sizeof(ip_s));
882 } else {
883 ovs_be128 ip6 = hton128(flow_get_xxreg(md, 0));
884 inet_ntop(AF_INET6, &ip6, ip_s, sizeof(ip_s));
885 }
886 uint32_t hash = hash_string(ip_s, hash_2words(dp_key, port_key));
887 struct put_mac_binding *pmb
888 = pinctrl_find_put_mac_binding(dp_key, port_key, ip_s, hash);
889 if (!pmb) {
890 if (hmap_count(&put_mac_bindings) >= 1000) {
891 COVERAGE_INC(pinctrl_drop_put_mac_binding);
0bac7164
BP
892 return;
893 }
894
c34a87b6
JP
895 pmb = xmalloc(sizeof *pmb);
896 hmap_insert(&put_mac_bindings, &pmb->hmap_node, hash);
897 pmb->dp_key = dp_key;
898 pmb->port_key = port_key;
899 ovs_strlcpy(pmb->ip_s, ip_s, sizeof pmb->ip_s);
0bac7164 900 }
c34a87b6
JP
901 pmb->timestamp = time_msec();
902 pmb->mac = headers->dl_src;
0bac7164
BP
903}
904
905static void
c34a87b6
JP
906run_put_mac_binding(struct controller_ctx *ctx,
907 const struct lport_index *lports,
908 const struct put_mac_binding *pmb)
0bac7164 909{
c34a87b6 910 if (time_msec() > pmb->timestamp + 1000) {
0bac7164
BP
911 return;
912 }
913
914 /* Convert logical datapath and logical port key into lport. */
915 const struct sbrec_port_binding *pb
c34a87b6 916 = lport_lookup_by_key(lports, pmb->dp_key, pmb->port_key);
0bac7164
BP
917 if (!pb) {
918 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
919
920 VLOG_WARN_RL(&rl, "unknown logical port with datapath %"PRIu32" "
c34a87b6 921 "and port %"PRIu32, pmb->dp_key, pmb->port_key);
0bac7164
BP
922 return;
923 }
924
c34a87b6 925 /* Convert ethernet argument to string form for database. */
0bac7164
BP
926 char mac_string[ETH_ADDR_STRLEN + 1];
927 snprintf(mac_string, sizeof mac_string,
c34a87b6 928 ETH_ADDR_FMT, ETH_ADDR_ARGS(pmb->mac));
0bac7164 929
c34a87b6 930 /* Check for an update an existing IP-MAC binding for this logical
0bac7164
BP
931 * port.
932 *
933 * XXX This is not very efficient. */
934 const struct sbrec_mac_binding *b;
935 SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) {
936 if (!strcmp(b->logical_port, pb->logical_port)
c34a87b6 937 && !strcmp(b->ip, pmb->ip_s)) {
0bac7164
BP
938 if (strcmp(b->mac, mac_string)) {
939 sbrec_mac_binding_set_mac(b, mac_string);
940 }
941 return;
942 }
943 }
944
945 /* Add new IP-MAC binding for this logical port. */
946 b = sbrec_mac_binding_insert(ctx->ovnsb_idl_txn);
947 sbrec_mac_binding_set_logical_port(b, pb->logical_port);
c34a87b6 948 sbrec_mac_binding_set_ip(b, pmb->ip_s);
0bac7164 949 sbrec_mac_binding_set_mac(b, mac_string);
791a7747 950 sbrec_mac_binding_set_datapath(b, pb->datapath);
0bac7164
BP
951}
952
953static void
c34a87b6
JP
954run_put_mac_bindings(struct controller_ctx *ctx,
955 const struct lport_index *lports)
0bac7164
BP
956{
957 if (!ctx->ovnsb_idl_txn) {
958 return;
959 }
960
c34a87b6
JP
961 const struct put_mac_binding *pmb;
962 HMAP_FOR_EACH (pmb, hmap_node, &put_mac_bindings) {
963 run_put_mac_binding(ctx, lports, pmb);
0bac7164 964 }
c34a87b6 965 flush_put_mac_bindings();
0bac7164
BP
966}
967
968static void
c34a87b6 969wait_put_mac_bindings(struct controller_ctx *ctx)
0bac7164 970{
c34a87b6 971 if (ctx->ovnsb_idl_txn && !hmap_is_empty(&put_mac_bindings)) {
0bac7164
BP
972 poll_immediate_wake();
973 }
974}
975
976static void
c34a87b6 977flush_put_mac_bindings(void)
0bac7164 978{
c34a87b6
JP
979 struct put_mac_binding *pmb;
980 HMAP_FOR_EACH_POP (pmb, hmap_node, &put_mac_bindings) {
981 free(pmb);
0bac7164 982 }
27732ac4 983}
0ee8aaf6
RR
984\f
985/*
986 * Send gratuitous ARP for vif on localnet.
987 *
988 * When a new vif on localnet is added, gratuitous ARPs are sent announcing
989 * the port's mac,ip mapping. On localnet, such announcements are needed for
990 * switches and routers on the broadcast segment to update their port-mac
991 * and ARP tables.
992 */
993struct garp_data {
994 struct eth_addr ea; /* Ethernet address of port. */
995 ovs_be32 ipv4; /* Ipv4 address of port. */
996 long long int announce_time; /* Next announcement in ms. */
997 int backoff; /* Backoff for the next announcement. */
58d04fb1 998 ofp_port_t ofport; /* ofport used to output this GARP. */
0ee8aaf6
RR
999};
1000
1001/* Contains GARPs to be sent. */
1002static struct shash send_garp_data;
1003
1004/* Next GARP announcement in ms. */
1005static long long int send_garp_time;
1006
1007static void
1008init_send_garps(void)
1009{
1010 shash_init(&send_garp_data);
1011 send_garp_time = LLONG_MAX;
1012}
1013
1014static void
1015destroy_send_garps(void)
1016{
1017 shash_destroy_free_data(&send_garp_data);
1018}
1019
8439c2eb
CSV
1020static void
1021add_garp(const char *name, ofp_port_t ofport,
1022 const struct eth_addr ea, ovs_be32 ip)
1023{
1024 struct garp_data *garp = xmalloc(sizeof *garp);
1025 garp->ea = ea;
1026 garp->ipv4 = ip;
1027 garp->announce_time = time_msec() + 1000;
1028 garp->backoff = 1;
1029 garp->ofport = ofport;
1030 shash_add(&send_garp_data, name, garp);
1031}
1032
0ee8aaf6
RR
1033/* Add or update a vif for which GARPs need to be announced. */
1034static void
1035send_garp_update(const struct sbrec_port_binding *binding_rec,
8439c2eb
CSV
1036 struct simap *localnet_ofports, struct hmap *local_datapaths,
1037 struct shash *nat_addresses)
0ee8aaf6
RR
1038{
1039 /* Find the localnet ofport to send this GARP. */
1040 struct local_datapath *ld
1041 = get_local_datapath(local_datapaths,
1042 binding_rec->datapath->tunnel_key);
1043 if (!ld || !ld->localnet_port) {
1044 return;
1045 }
58d04fb1
BP
1046 ofp_port_t ofport = u16_to_ofp(simap_get(localnet_ofports,
1047 ld->localnet_port->logical_port));
0ee8aaf6 1048
8439c2eb
CSV
1049 volatile struct garp_data *garp = NULL;
1050 /* Update GARP for NAT IP if it exists. */
1051 if (!strcmp(binding_rec->type, "l3gateway")) {
1052 struct lport_addresses *laddrs = NULL;
1053 laddrs = shash_find_data(nat_addresses, binding_rec->logical_port);
1054 if (!laddrs) {
1055 return;
1056 }
1057 int i;
1058 for (i = 0; i < laddrs->n_ipv4_addrs; i++) {
1059 char *name = xasprintf("%s-%s", binding_rec->logical_port,
1060 laddrs->ipv4_addrs[i].addr_s);
1061 garp = shash_find_data(&send_garp_data, name);
1062 if (garp) {
1063 garp->ofport = ofport;
1064 } else {
1065 add_garp(name, ofport, laddrs->ea, laddrs->ipv4_addrs[i].addr);
1066 }
1067 free(name);
1068 }
8439c2eb
CSV
1069 return;
1070 }
1071
1072 /* Update GARP for vif if it exists. */
1073 garp = shash_find_data(&send_garp_data, binding_rec->logical_port);
0ee8aaf6
RR
1074 if (garp) {
1075 garp->ofport = ofport;
1076 return;
1077 }
1078
1079 /* Add GARP for new vif. */
1080 int i;
1081 for (i = 0; i < binding_rec->n_mac; i++) {
1082 struct lport_addresses laddrs;
5942a98d 1083 if (!extract_lsp_addresses(binding_rec->mac[i], &laddrs)
0ee8aaf6
RR
1084 || !laddrs.n_ipv4_addrs) {
1085 continue;
1086 }
1087
8439c2eb
CSV
1088 add_garp(binding_rec->logical_port, ofport,
1089 laddrs.ea, laddrs.ipv4_addrs[0].addr);
0ee8aaf6 1090
f2a715b5 1091 destroy_lport_addresses(&laddrs);
0ee8aaf6
RR
1092 break;
1093 }
1094}
1095
1096/* Remove a vif from GARP announcements. */
1097static void
1098send_garp_delete(const char *lport)
1099{
1100 struct garp_data *garp = shash_find_and_delete(&send_garp_data, lport);
1101 free(garp);
1102}
1103
1104static long long int
1105send_garp(struct garp_data *garp, long long int current_time)
1106{
1107 if (current_time < garp->announce_time) {
1108 return garp->announce_time;
1109 }
1110
1111 /* Compose a GARP request packet. */
1112 uint64_t packet_stub[128 / 8];
1113 struct dp_packet packet;
1114 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
1115 compose_arp(&packet, ARP_OP_REQUEST, garp->ea, eth_addr_zero,
1116 true, garp->ipv4, garp->ipv4);
1117
1118 /* Compose actions. The garp request is output on localnet ofport. */
1119 uint64_t ofpacts_stub[4096 / 8];
1120 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
1121 enum ofp_version version = rconn_get_version(swconn);
1122 ofpact_put_OUTPUT(&ofpacts)->port = garp->ofport;
1123
1124 struct ofputil_packet_out po = {
1125 .packet = dp_packet_data(&packet),
1126 .packet_len = dp_packet_size(&packet),
1127 .buffer_id = UINT32_MAX,
1128 .in_port = OFPP_CONTROLLER,
1129 .ofpacts = ofpacts.data,
1130 .ofpacts_len = ofpacts.size,
1131 };
1132 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
1133 queue_msg(ofputil_encode_packet_out(&po, proto));
1134 dp_packet_uninit(&packet);
1135 ofpbuf_uninit(&ofpacts);
1136
1137 /* Set the next announcement. At most 5 announcements are sent for a
1138 * vif. */
1139 if (garp->backoff < 16) {
1140 garp->backoff *= 2;
1141 garp->announce_time = current_time + garp->backoff * 1000;
1142 } else {
1143 garp->announce_time = LLONG_MAX;
1144 }
1145 return garp->announce_time;
1146}
1147
8439c2eb 1148/* Get localnet vifs, local l3gw ports and ofport for localnet patch ports. */
0ee8aaf6 1149static void
8439c2eb 1150get_localnet_vifs_l3gwports(const struct ovsrec_bridge *br_int,
f1a8bd06 1151 const struct sbrec_chassis *chassis,
0ee8aaf6
RR
1152 const struct lport_index *lports,
1153 struct hmap *local_datapaths,
1154 struct sset *localnet_vifs,
8439c2eb
CSV
1155 struct simap *localnet_ofports,
1156 struct sset *local_l3gw_ports)
0ee8aaf6
RR
1157{
1158 for (int i = 0; i < br_int->n_ports; i++) {
1159 const struct ovsrec_port *port_rec = br_int->ports[i];
1160 if (!strcmp(port_rec->name, br_int->name)) {
1161 continue;
1162 }
1163 const char *chassis_id = smap_get(&port_rec->external_ids,
1164 "ovn-chassis-id");
f1a8bd06 1165 if (chassis_id && !strcmp(chassis_id, chassis->name)) {
0ee8aaf6
RR
1166 continue;
1167 }
1168 const char *localnet = smap_get(&port_rec->external_ids,
1169 "ovn-localnet-port");
1170 for (int j = 0; j < port_rec->n_interfaces; j++) {
1171 const struct ovsrec_interface *iface_rec = port_rec->interfaces[j];
1172 if (!iface_rec->n_ofport) {
1173 continue;
1174 }
1175 if (localnet) {
1176 int64_t ofport = iface_rec->ofport[0];
1177 if (ofport < 1 || ofport > ofp_to_u16(OFPP_MAX)) {
1178 continue;
1179 }
1180 simap_put(localnet_ofports, localnet, ofport);
1181 continue;
1182 }
1183 const char *iface_id = smap_get(&iface_rec->external_ids,
1184 "iface-id");
1185 if (!iface_id) {
1186 continue;
1187 }
1188 const struct sbrec_port_binding *pb
1189 = lport_lookup_by_name(lports, iface_id);
1190 if (!pb) {
1191 continue;
1192 }
1193 struct local_datapath *ld
1194 = get_local_datapath(local_datapaths,
1195 pb->datapath->tunnel_key);
1196 if (ld && ld->localnet_port) {
1197 sset_add(localnet_vifs, iface_id);
1198 }
1199 }
1200 }
f1a8bd06
BP
1201
1202 const struct local_datapath *ld;
1203 HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
1204 if (!ld->has_local_l3gateway) {
1205 continue;
1206 }
1207
1208 for (size_t i = 0; i < ld->ldatapath->n_lports; i++) {
1209 const struct sbrec_port_binding *pb = ld->ldatapath->lports[i];
1210 if (!strcmp(pb->type, "l3gateway")
1211 /* && it's on this chassis */) {
1212 sset_add(local_l3gw_ports, pb->logical_port);
1213 }
1214 }
1215 }
0ee8aaf6
RR
1216}
1217
8439c2eb
CSV
1218static void
1219get_nat_addresses_and_keys(struct sset *nat_address_keys,
1220 struct sset *local_l3gw_ports,
1221 const struct lport_index *lports,
1222 struct shash *nat_addresses)
1223{
1224 const char *gw_port;
1225 SSET_FOR_EACH(gw_port, local_l3gw_ports) {
1226 const struct sbrec_port_binding *pb = lport_lookup_by_name(lports,
1227 gw_port);
1228 if (!pb) {
1229 continue;
1230 }
1231 const char *nat_addresses_options = smap_get(&pb->options,
1232 "nat-addresses");
1233 if (!nat_addresses_options) {
1234 continue;
1235 }
1236
1237 struct lport_addresses *laddrs = xmalloc(sizeof *laddrs);
1238 if (!extract_lsp_addresses(nat_addresses_options, laddrs)) {
1239 free(laddrs);
1240 continue;
1241 }
1242 int i;
1243 for (i = 0; i < laddrs->n_ipv4_addrs; i++) {
1244 char *name = xasprintf("%s-%s", pb->logical_port,
1245 laddrs->ipv4_addrs[i].addr_s);
1246 sset_add(nat_address_keys, name);
1247 free(name);
1248 }
1249 shash_add(nat_addresses, pb->logical_port, laddrs);
1250 }
1251}
1252
0ee8aaf6
RR
1253static void
1254send_garp_wait(void)
1255{
1256 poll_timer_wait_until(send_garp_time);
1257}
1258
1259static void
f1a8bd06
BP
1260send_garp_run(const struct ovsrec_bridge *br_int,
1261 const struct sbrec_chassis *chassis,
0ee8aaf6
RR
1262 const struct lport_index *lports,
1263 struct hmap *local_datapaths)
1264{
1265 struct sset localnet_vifs = SSET_INITIALIZER(&localnet_vifs);
8439c2eb
CSV
1266 struct sset local_l3gw_ports = SSET_INITIALIZER(&local_l3gw_ports);
1267 struct sset nat_ip_keys = SSET_INITIALIZER(&nat_ip_keys);
0ee8aaf6 1268 struct simap localnet_ofports = SIMAP_INITIALIZER(&localnet_ofports);
8439c2eb 1269 struct shash nat_addresses;
0ee8aaf6 1270
8439c2eb 1271 shash_init(&nat_addresses);
0ee8aaf6 1272
f1a8bd06 1273 get_localnet_vifs_l3gwports(br_int, chassis, lports, local_datapaths,
8439c2eb
CSV
1274 &localnet_vifs, &localnet_ofports, &local_l3gw_ports);
1275
1276 get_nat_addresses_and_keys(&nat_ip_keys, &local_l3gw_ports, lports,
1277 &nat_addresses);
1278 /* For deleted ports and deleted nat ips, remove from send_garp_data. */
0ee8aaf6
RR
1279 struct shash_node *iter, *next;
1280 SHASH_FOR_EACH_SAFE (iter, next, &send_garp_data) {
8439c2eb
CSV
1281 if (!sset_contains(&localnet_vifs, iter->name) &&
1282 !sset_contains(&nat_ip_keys, iter->name)) {
0ee8aaf6
RR
1283 send_garp_delete(iter->name);
1284 }
1285 }
1286
1287 /* Update send_garp_data. */
1288 const char *iface_id;
1289 SSET_FOR_EACH (iface_id, &localnet_vifs) {
1290 const struct sbrec_port_binding *pb = lport_lookup_by_name(lports,
1291 iface_id);
1292 if (pb) {
8439c2eb
CSV
1293 send_garp_update(pb, &localnet_ofports, local_datapaths,
1294 &nat_addresses);
1295 }
1296 }
1297
1298 /* Update send_garp_data for nat-addresses. */
1299 const char *gw_port;
1300 SSET_FOR_EACH (gw_port, &local_l3gw_ports) {
1301 const struct sbrec_port_binding *pb = lport_lookup_by_name(lports,
1302 gw_port);
1303 if (pb) {
1304 send_garp_update(pb, &localnet_ofports, local_datapaths,
1305 &nat_addresses);
0ee8aaf6
RR
1306 }
1307 }
1308
1309 /* Send GARPs, and update the next announcement. */
1310 long long int current_time = time_msec();
1311 send_garp_time = LLONG_MAX;
1312 SHASH_FOR_EACH (iter, &send_garp_data) {
1313 long long int next_announce = send_garp(iter->data, current_time);
1314 if (send_garp_time > next_announce) {
1315 send_garp_time = next_announce;
1316 }
1317 }
1318 sset_destroy(&localnet_vifs);
8439c2eb 1319 sset_destroy(&local_l3gw_ports);
0ee8aaf6 1320 simap_destroy(&localnet_ofports);
02d1f722
BP
1321
1322 SHASH_FOR_EACH_SAFE (iter, next, &nat_addresses) {
1323 struct lport_addresses *laddrs = iter->data;
1324 destroy_lport_addresses(laddrs);
1325 shash_delete(&nat_addresses, iter);
1326 free(laddrs);
1327 }
1328 shash_destroy(&nat_addresses);
1329
96a234ad 1330 sset_destroy(&nat_ip_keys);
0ee8aaf6 1331}
e75451fe
ZKL
1332
1333static void
1334reload_metadata(struct ofpbuf *ofpacts, const struct match *md)
1335{
1336 enum mf_field_id md_fields[] = {
847b8b02 1337#if FLOW_N_REGS == 16
e75451fe
ZKL
1338 MFF_REG0,
1339 MFF_REG1,
1340 MFF_REG2,
1341 MFF_REG3,
1342 MFF_REG4,
1343 MFF_REG5,
1344 MFF_REG6,
1345 MFF_REG7,
847b8b02
JP
1346 MFF_REG8,
1347 MFF_REG9,
1348 MFF_REG10,
1349 MFF_REG11,
1350 MFF_REG12,
1351 MFF_REG13,
1352 MFF_REG14,
1353 MFF_REG15,
e75451fe
ZKL
1354#else
1355#error
1356#endif
1357 MFF_METADATA,
1358 };
1359 for (size_t i = 0; i < ARRAY_SIZE(md_fields); i++) {
1360 const struct mf_field *field = mf_from_id(md_fields[i]);
1361 if (!mf_is_all_wild(field, &md->wc)) {
128684a6
JR
1362 union mf_value value;
1363 mf_get_value(field, &md->flow, &value);
1364 ofpact_put_set_field(ofpacts, field, &value, NULL);
e75451fe
ZKL
1365 }
1366 }
1367}
1368
1369static void
f8a8db39
JP
1370pinctrl_handle_nd_na(const struct flow *ip_flow, const struct match *md,
1371 struct ofpbuf *userdata)
e75451fe
ZKL
1372{
1373 /* This action only works for IPv6 ND packets, and the switch should only
1374 * send us ND packets this way, but check here just to be sure. */
1375 if (!is_nd(ip_flow, NULL)) {
1376 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1377 VLOG_WARN_RL(&rl, "NA action on non-ND packet");
1378 return;
1379 }
1380
1381 enum ofp_version version = rconn_get_version(swconn);
1382 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
1383
1384 uint64_t packet_stub[128 / 8];
1385 struct dp_packet packet;
1386 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
1387
fa7f915c
JP
1388 /* xxx These flags are not exactly correct. Look at section 7.2.4
1389 * xxx of RFC 4861. For example, we need to set ND_RSO_ROUTER for
1390 * xxx router's interfaces and ND_RSO_SOLICITED only if it was
1391 * xxx requested. */
16187903
JP
1392 compose_nd_na(&packet, ip_flow->dl_dst, ip_flow->dl_src,
1393 &ip_flow->nd_target, &ip_flow->ipv6_src,
1394 htonl(ND_RSO_SOLICITED | ND_RSO_OVERRIDE));
e75451fe
ZKL
1395
1396 /* Reload previous packet metadata. */
1397 uint64_t ofpacts_stub[4096 / 8];
1398 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
1399 reload_metadata(&ofpacts, md);
1400
1401 enum ofperr error = ofpacts_pull_openflow_actions(userdata, userdata->size,
5c7c16d8
YHW
1402 version, NULL, NULL,
1403 &ofpacts);
e75451fe
ZKL
1404 if (error) {
1405 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1406 VLOG_WARN_RL(&rl, "failed to parse actions for 'na' (%s)",
1407 ofperr_to_string(error));
1408 goto exit;
1409 }
1410
1411 struct ofputil_packet_out po = {
1412 .packet = dp_packet_data(&packet),
1413 .packet_len = dp_packet_size(&packet),
1414 .buffer_id = UINT32_MAX,
1415 .in_port = OFPP_CONTROLLER,
1416 .ofpacts = ofpacts.data,
1417 .ofpacts_len = ofpacts.size,
1418 };
1419
1420 queue_msg(ofputil_encode_packet_out(&po, proto));
1421
1422exit:
1423 dp_packet_uninit(&packet);
1424 ofpbuf_uninit(&ofpacts);
1425}