1 /* Copyright (c) 2015, 2016 Red Hat, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
23 #include "dp-packet.h"
27 #include "ovn-controller.h"
28 #include "lib/packets.h"
30 #include "openvswitch/ofp-actions.h"
31 #include "openvswitch/ofp-msgs.h"
32 #include "openvswitch/ofp-print.h"
33 #include "openvswitch/ofp-util.h"
34 #include "openvswitch/vlog.h"
37 #include "ovn-controller.h"
38 #include "ovn/lib/actions.h"
39 #include "ovn/lib/logical-fields.h"
40 #include "ovn/lib/ovn-util.h"
41 #include "poll-loop.h"
43 #include "socket-util.h"
45 #include "vswitch-idl.h"
47 VLOG_DEFINE_THIS_MODULE(pinctrl);
49 /* OpenFlow connection to the switch. */
50 static struct rconn *swconn;
52 /* Last seen sequence number for 'swconn'. When this differs from
53 * rconn_get_connection_seqno(rconn), 'swconn' has reconnected. */
54 static unsigned int conn_seq_no;
56 static void pinctrl_handle_put_arp(const struct flow *md,
57 const struct flow *headers);
58 static void init_put_arps(void);
59 static void destroy_put_arps(void);
60 static void run_put_arps(struct controller_ctx *,
61 const struct lport_index *lports);
62 static void wait_put_arps(struct controller_ctx *);
63 static void flush_put_arps(void);
65 static void init_send_garps(void);
66 static void destroy_send_garps(void);
67 static void send_garp_wait(void);
68 static void send_garp_run(const struct ovsrec_bridge *,
69 const char *chassis_id,
70 const struct lport_index *lports,
71 struct hmap *local_datapaths);
72 static void pinctrl_handle_na(const struct flow *ip_flow,
73 const struct match *md,
74 struct ofpbuf *userdata);
75 static void reload_metadata(struct ofpbuf *ofpacts,
76 const struct match *md);
78 COVERAGE_DEFINE(pinctrl_drop_put_arp);
83 swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
90 queue_msg(struct ofpbuf *msg)
92 const struct ofp_header *oh = msg->data;
93 ovs_be32 xid = oh->xid;
95 rconn_send(swconn, msg, NULL);
99 /* Sets up 'swconn', a newly (re)connected connection to a switch. */
101 pinctrl_setup(struct rconn *swconn)
103 /* Fetch the switch configuration. The response later will allow us to
104 * change the miss_send_len to UINT16_MAX, so that we can enable
105 * asynchronous messages. */
106 queue_msg(ofpraw_alloc(OFPRAW_OFPT_GET_CONFIG_REQUEST,
107 rconn_get_version(swconn), 0));
109 /* Set a packet-in format that supports userdata. */
110 queue_msg(ofputil_make_set_packet_in_format(rconn_get_version(swconn),
111 NXPIF_NXT_PACKET_IN2));
115 set_switch_config(struct rconn *swconn,
116 const struct ofputil_switch_config *config)
118 enum ofp_version version = rconn_get_version(swconn);
119 struct ofpbuf *request = ofputil_encode_set_config(config, version);
124 pinctrl_handle_arp(const struct flow *ip_flow, const struct match *md,
125 struct ofpbuf *userdata)
127 /* This action only works for IP packets, and the switch should only send
128 * us IP packets this way, but check here just to be sure. */
129 if (ip_flow->dl_type != htons(ETH_TYPE_IP)) {
130 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
131 VLOG_WARN_RL(&rl, "ARP action on non-IP packet (Ethertype %"PRIx16")",
132 ntohs(ip_flow->dl_type));
136 /* Compose an ARP packet. */
137 uint64_t packet_stub[128 / 8];
138 struct dp_packet packet;
139 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
140 compose_arp__(&packet);
142 struct eth_header *eth = dp_packet_l2(&packet);
143 eth->eth_dst = ip_flow->dl_dst;
144 eth->eth_src = ip_flow->dl_src;
146 struct arp_eth_header *arp = dp_packet_l3(&packet);
147 arp->ar_op = htons(ARP_OP_REQUEST);
148 arp->ar_sha = ip_flow->dl_src;
149 put_16aligned_be32(&arp->ar_spa, ip_flow->nw_src);
150 arp->ar_tha = eth_addr_zero;
151 put_16aligned_be32(&arp->ar_tpa, ip_flow->nw_dst);
153 if (ip_flow->vlan_tci & htons(VLAN_CFI)) {
154 eth_push_vlan(&packet, htons(ETH_TYPE_VLAN_8021Q), ip_flow->vlan_tci);
159 * First, copy metadata from 'md' into the packet-out via "set_field"
160 * actions, then add actions from 'userdata'.
162 uint64_t ofpacts_stub[4096 / 8];
163 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
164 enum ofp_version version = rconn_get_version(swconn);
166 reload_metadata(&ofpacts, md);
167 enum ofperr error = ofpacts_pull_openflow_actions(userdata, userdata->size, version, &ofpacts);
169 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
170 VLOG_WARN_RL(&rl, "failed to parse arp actions (%s)",
171 ofperr_to_string(error));
175 struct ofputil_packet_out po = {
176 .packet = dp_packet_data(&packet),
177 .packet_len = dp_packet_size(&packet),
178 .buffer_id = UINT32_MAX,
179 .in_port = OFPP_CONTROLLER,
180 .ofpacts = ofpacts.data,
181 .ofpacts_len = ofpacts.size,
183 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
184 queue_msg(ofputil_encode_packet_out(&po, proto));
187 dp_packet_uninit(&packet);
188 ofpbuf_uninit(&ofpacts);
192 pinctrl_handle_put_dhcp_opts(
193 struct dp_packet *pkt_in, struct ofputil_packet_in *pin,
194 struct ofpbuf *userdata, struct ofpbuf *continuation)
196 enum ofp_version version = rconn_get_version(swconn);
197 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
198 struct dp_packet *pkt_out_ptr = NULL;
199 uint32_t success = 0;
201 /* Parse result field. */
202 const struct mf_field *f;
203 enum ofperr ofperr = nx_pull_header(userdata, &f, NULL);
205 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
206 VLOG_WARN_RL(&rl, "bad result OXM (%s)", ofperr_to_string(ofperr));
210 /* Parse result offset and offer IP. */
211 ovs_be32 *ofsp = ofpbuf_try_pull(userdata, sizeof *ofsp);
212 ovs_be32 *offer_ip = ofpbuf_try_pull(userdata, sizeof *offer_ip);
213 if (!ofsp || !offer_ip) {
214 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
215 VLOG_WARN_RL(&rl, "offset or offer_ip not present in the userdata");
219 /* Check that the result is valid and writable. */
220 struct mf_subfield dst = { .field = f, .ofs = ntohl(*ofsp), .n_bits = 1 };
221 ofperr = mf_check_dst(&dst, NULL);
223 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
224 VLOG_WARN_RL(&rl, "bad result bit (%s)", ofperr_to_string(ofperr));
228 if (!userdata->size) {
229 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
230 VLOG_WARN_RL(&rl, "DHCP options not present in the userdata");
234 /* Validate the DHCP request packet.
235 * Format of the DHCP packet is
236 * ------------------------------------------------------------------------
237 *| UDP HEADER | DHCP HEADER | 4 Byte DHCP Cookie | DHCP OPTIONS(var len)|
238 * ------------------------------------------------------------------------
240 if (dp_packet_l4_size(pkt_in) < (UDP_HEADER_LEN +
241 sizeof (struct dhcp_header) + sizeof(uint32_t) + 3)) {
242 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
243 VLOG_WARN_RL(&rl, "Invalid or incomplete DHCP packet recieved");
247 struct dhcp_header const *in_dhcp_data = dp_packet_get_udp_payload(pkt_in);
248 if (in_dhcp_data->op != DHCP_OP_REQUEST) {
249 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
250 VLOG_WARN_RL(&rl, "Invalid opcode in the DHCP packet : %d",
255 /* DHCP options follow the DHCP header. The first 4 bytes of the DHCP
256 * options is the DHCP magic cookie followed by the actual DHCP options.
258 const uint8_t *in_dhcp_opt =
259 (const uint8_t *)dp_packet_get_udp_payload(pkt_in) +
260 sizeof (struct dhcp_header);
262 ovs_be32 magic_cookie = htonl(DHCP_MAGIC_COOKIE);
263 if (memcmp(in_dhcp_opt, &magic_cookie, sizeof(ovs_be32))) {
264 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
265 VLOG_WARN_RL(&rl, "DHCP magic cookie not present in the DHCP packet");
270 /* Check that the DHCP Message Type (opt 53) is present or not with
271 * valid values - DHCP_MSG_DISCOVER or DHCP_MSG_REQUEST as the first
274 if (!(in_dhcp_opt[0] == DHCP_OPT_MSG_TYPE && in_dhcp_opt[1] == 1 && (
275 in_dhcp_opt[2] == DHCP_MSG_DISCOVER ||
276 in_dhcp_opt[2] == DHCP_MSG_REQUEST))) {
277 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
278 VLOG_WARN_RL(&rl, "Invalid DHCP message type : opt code = %d,"
279 " opt value = %d", in_dhcp_opt[0], in_dhcp_opt[2]);
284 if (in_dhcp_opt[2] == DHCP_MSG_DISCOVER) {
285 msg_type = DHCP_MSG_OFFER;
287 msg_type = DHCP_MSG_ACK;
290 /* Frame the DHCP reply packet
291 * Total DHCP options length will be options stored in the userdata +
294 * --------------------------------------------------------------
295 *| 4 Bytes (dhcp cookie) | 3 Bytes (option type) | DHCP options |
296 * --------------------------------------------------------------
297 *| 4 Bytes padding | 1 Byte (option end 0xFF ) | 4 Bytes padding|
298 * --------------------------------------------------------------
300 uint16_t new_l4_size = UDP_HEADER_LEN + DHCP_HEADER_LEN + \
302 size_t new_packet_size = pkt_in->l4_ofs + new_l4_size;
304 struct dp_packet pkt_out;
305 dp_packet_init(&pkt_out, new_packet_size);
306 dp_packet_clear(&pkt_out);
307 dp_packet_prealloc_tailroom(&pkt_out, new_packet_size);
308 pkt_out_ptr = &pkt_out;
310 /* Copy the L2 and L3 headers from the pkt_in as they would remain same*/
312 &pkt_out, dp_packet_pull(pkt_in, pkt_in->l4_ofs), pkt_in->l4_ofs);
314 pkt_out.l2_5_ofs = pkt_in->l2_5_ofs;
315 pkt_out.l2_pad_size = pkt_in->l2_pad_size;
316 pkt_out.l3_ofs = pkt_in->l3_ofs;
317 pkt_out.l4_ofs = pkt_in->l4_ofs;
319 struct udp_header *udp = dp_packet_put(
320 &pkt_out, dp_packet_pull(pkt_in, UDP_HEADER_LEN), UDP_HEADER_LEN);
322 struct dhcp_header *dhcp_data = dp_packet_put(
323 &pkt_out, dp_packet_pull(pkt_in, DHCP_HEADER_LEN), DHCP_HEADER_LEN);
324 dhcp_data->op = DHCP_OP_REPLY;
325 dhcp_data->yiaddr = *offer_ip;
326 dp_packet_put(&pkt_out, &magic_cookie, sizeof(ovs_be32));
328 uint8_t *out_dhcp_opts = dp_packet_put_zeros(&pkt_out,
329 userdata->size + 12);
330 /* DHCP option - type */
331 out_dhcp_opts[0] = DHCP_OPT_MSG_TYPE;
332 out_dhcp_opts[1] = 1;
333 out_dhcp_opts[2] = msg_type;
336 memcpy(out_dhcp_opts, userdata->data, userdata->size);
337 out_dhcp_opts += userdata->size;
341 out_dhcp_opts[0] = DHCP_OPT_END;
343 udp->udp_len = htons(new_l4_size);
345 struct ip_header *out_ip = dp_packet_l3(&pkt_out);
346 out_ip->ip_tot_len = htons(pkt_out.l4_ofs - pkt_out.l3_ofs + new_l4_size);
349 out_ip->ip_csum = csum(out_ip, sizeof *out_ip);
351 pin->packet = dp_packet_data(&pkt_out);
352 pin->packet_len = dp_packet_size(&pkt_out);
357 union mf_subvalue sv;
359 mf_write_subfield(&dst, &sv, &pin->flow_metadata);
361 queue_msg(ofputil_encode_resume(pin, continuation, proto));
363 dp_packet_uninit(pkt_out_ptr);
368 process_packet_in(const struct ofp_header *msg)
370 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
372 struct ofputil_packet_in pin;
373 struct ofpbuf continuation;
374 enum ofperr error = ofputil_decode_packet_in(msg, true, &pin,
375 NULL, NULL, &continuation);
378 VLOG_WARN_RL(&rl, "error decoding packet-in: %s",
379 ofperr_to_string(error));
382 if (pin.reason != OFPR_ACTION) {
386 struct ofpbuf userdata = ofpbuf_const_initializer(pin.userdata,
388 const struct action_header *ah = ofpbuf_pull(&userdata, sizeof *ah);
390 VLOG_WARN_RL(&rl, "packet-in userdata lacks action header");
394 struct dp_packet packet;
395 dp_packet_use_const(&packet, pin.packet, pin.packet_len);
397 flow_extract(&packet, &headers);
399 switch (ntohl(ah->opcode)) {
400 case ACTION_OPCODE_ARP:
401 pinctrl_handle_arp(&headers, &pin.flow_metadata, &userdata);
404 case ACTION_OPCODE_PUT_ARP:
405 pinctrl_handle_put_arp(&pin.flow_metadata.flow, &headers);
408 case ACTION_OPCODE_PUT_DHCP_OPTS:
409 pinctrl_handle_put_dhcp_opts(&packet, &pin, &userdata, &continuation);
412 case ACTION_OPCODE_NA:
413 pinctrl_handle_na(&headers, &pin.flow_metadata, &userdata);
417 VLOG_WARN_RL(&rl, "unrecognized packet-in opcode %"PRIu32,
424 pinctrl_recv(const struct ofp_header *oh, enum ofptype type)
426 if (type == OFPTYPE_ECHO_REQUEST) {
427 queue_msg(make_echo_reply(oh));
428 } else if (type == OFPTYPE_GET_CONFIG_REPLY) {
429 /* Enable asynchronous messages (see "Asynchronous Messages" in
430 * DESIGN.md for more information). */
431 struct ofputil_switch_config config;
433 ofputil_decode_get_config_reply(oh, &config);
434 config.miss_send_len = UINT16_MAX;
435 set_switch_config(swconn, &config);
436 } else if (type == OFPTYPE_PACKET_IN) {
437 process_packet_in(oh);
438 } else if (type != OFPTYPE_ECHO_REPLY && type != OFPTYPE_BARRIER_REPLY) {
439 if (VLOG_IS_DBG_ENABLED()) {
440 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
442 char *s = ofp_to_string(oh, ntohs(oh->length), 2);
444 VLOG_DBG_RL(&rl, "OpenFlow packet ignored: %s", s);
451 pinctrl_run(struct controller_ctx *ctx, const struct lport_index *lports,
452 const struct ovsrec_bridge *br_int,
453 const char *chassis_id,
454 struct hmap *local_datapaths)
459 target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
460 if (strcmp(target, rconn_get_target(swconn))) {
461 VLOG_INFO("%s: connecting to switch", target);
462 rconn_connect(swconn, target, target);
466 rconn_disconnect(swconn);
471 if (rconn_is_connected(swconn)) {
472 if (conn_seq_no != rconn_get_connection_seqno(swconn)) {
473 pinctrl_setup(swconn);
474 conn_seq_no = rconn_get_connection_seqno(swconn);
478 /* Process a limited number of messages per call. */
479 for (int i = 0; i < 50; i++) {
480 struct ofpbuf *msg = rconn_recv(swconn);
485 const struct ofp_header *oh = msg->data;
488 ofptype_decode(&type, oh);
489 pinctrl_recv(oh, type);
494 run_put_arps(ctx, lports);
495 send_garp_run(br_int, chassis_id, lports, local_datapaths);
499 pinctrl_wait(struct controller_ctx *ctx)
502 rconn_run_wait(swconn);
503 rconn_recv_wait(swconn);
508 pinctrl_destroy(void)
510 rconn_destroy(swconn);
512 destroy_send_garps();
515 /* Implementation of the "put_arp" OVN action. This action sends a packet to
516 * ovn-controller, using the flow as an API (see actions.h for details). This
517 * code implements the action by updating the MAC_Binding table in the
518 * southbound database.
520 * This code could be a lot simpler if the database could always be updated,
521 * but in fact we can only update it when ctx->ovnsb_idl_txn is nonnull. Thus,
522 * we buffer up a few put_arps (but we don't keep them longer than 1 second)
523 * and apply them whenever a database transaction is available. */
525 /* Buffered "put_arp" operation. */
527 struct hmap_node hmap_node; /* In 'put_arps'. */
529 long long int timestamp; /* In milliseconds. */
540 /* Contains "struct put_arp"s. */
541 static struct hmap put_arps;
546 hmap_init(&put_arps);
550 destroy_put_arps(void)
553 hmap_destroy(&put_arps);
556 static struct put_arp *
557 pinctrl_find_put_arp(uint32_t dp_key, uint32_t port_key, ovs_be32 ip,
561 HMAP_FOR_EACH_WITH_HASH (pa, hmap_node, hash, &put_arps) {
562 if (pa->dp_key == dp_key
563 && pa->port_key == port_key
572 pinctrl_handle_put_arp(const struct flow *md, const struct flow *headers)
574 uint32_t dp_key = ntohll(md->metadata);
575 uint32_t port_key = md->regs[MFF_LOG_INPORT - MFF_REG0];
576 ovs_be32 ip = htonl(md->regs[0]);
577 uint32_t hash = hash_3words(dp_key, port_key, (OVS_FORCE uint32_t) ip);
578 struct put_arp *pa = pinctrl_find_put_arp(dp_key, port_key, ip, hash);
580 if (hmap_count(&put_arps) >= 1000) {
581 COVERAGE_INC(pinctrl_drop_put_arp);
585 pa = xmalloc(sizeof *pa);
586 hmap_insert(&put_arps, &pa->hmap_node, hash);
588 pa->port_key = port_key;
591 pa->timestamp = time_msec();
592 pa->mac = headers->dl_src;
596 run_put_arp(struct controller_ctx *ctx, const struct lport_index *lports,
597 const struct put_arp *pa)
599 if (time_msec() > pa->timestamp + 1000) {
603 /* Convert logical datapath and logical port key into lport. */
604 const struct sbrec_port_binding *pb
605 = lport_lookup_by_key(lports, pa->dp_key, pa->port_key);
607 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
609 VLOG_WARN_RL(&rl, "unknown logical port with datapath %"PRIu32" "
610 "and port %"PRIu32, pa->dp_key, pa->port_key);
614 /* Convert arguments to string form for database. */
615 char ip_string[INET_ADDRSTRLEN + 1];
616 snprintf(ip_string, sizeof ip_string, IP_FMT, IP_ARGS(pa->ip));
618 char mac_string[ETH_ADDR_STRLEN + 1];
619 snprintf(mac_string, sizeof mac_string,
620 ETH_ADDR_FMT, ETH_ADDR_ARGS(pa->mac));
622 /* Check for and update an existing IP-MAC binding for this logical
625 * XXX This is not very efficient. */
626 const struct sbrec_mac_binding *b;
627 SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) {
628 if (!strcmp(b->logical_port, pb->logical_port)
629 && !strcmp(b->ip, ip_string)) {
630 if (strcmp(b->mac, mac_string)) {
631 sbrec_mac_binding_set_mac(b, mac_string);
637 /* Add new IP-MAC binding for this logical port. */
638 b = sbrec_mac_binding_insert(ctx->ovnsb_idl_txn);
639 sbrec_mac_binding_set_logical_port(b, pb->logical_port);
640 sbrec_mac_binding_set_ip(b, ip_string);
641 sbrec_mac_binding_set_mac(b, mac_string);
642 sbrec_mac_binding_set_datapath(b, pb->datapath);
646 run_put_arps(struct controller_ctx *ctx, const struct lport_index *lports)
648 if (!ctx->ovnsb_idl_txn) {
652 const struct put_arp *pa;
653 HMAP_FOR_EACH (pa, hmap_node, &put_arps) {
654 run_put_arp(ctx, lports, pa);
660 wait_put_arps(struct controller_ctx *ctx)
662 if (ctx->ovnsb_idl_txn && !hmap_is_empty(&put_arps)) {
663 poll_immediate_wake();
671 HMAP_FOR_EACH_POP (pa, hmap_node, &put_arps) {
677 * Send gratuitous ARP for vif on localnet.
679 * When a new vif on localnet is added, gratuitous ARPs are sent announcing
680 * the port's mac,ip mapping. On localnet, such announcements are needed for
681 * switches and routers on the broadcast segment to update their port-mac
685 struct eth_addr ea; /* Ethernet address of port. */
686 ovs_be32 ipv4; /* Ipv4 address of port. */
687 long long int announce_time; /* Next announcement in ms. */
688 int backoff; /* Backoff for the next announcement. */
689 ofp_port_t ofport; /* ofport used to output this GARP. */
692 /* Contains GARPs to be sent. */
693 static struct shash send_garp_data;
695 /* Next GARP announcement in ms. */
696 static long long int send_garp_time;
699 init_send_garps(void)
701 shash_init(&send_garp_data);
702 send_garp_time = LLONG_MAX;
706 destroy_send_garps(void)
708 shash_destroy_free_data(&send_garp_data);
711 /* Add or update a vif for which GARPs need to be announced. */
713 send_garp_update(const struct sbrec_port_binding *binding_rec,
714 struct simap *localnet_ofports, struct hmap *local_datapaths)
716 /* Find the localnet ofport to send this GARP. */
717 struct local_datapath *ld
718 = get_local_datapath(local_datapaths,
719 binding_rec->datapath->tunnel_key);
720 if (!ld || !ld->localnet_port) {
723 ofp_port_t ofport = u16_to_ofp(simap_get(localnet_ofports,
724 ld->localnet_port->logical_port));
726 /* Update GARP if it exists. */
727 struct garp_data *garp = shash_find_data(&send_garp_data,
728 binding_rec->logical_port);
730 garp->ofport = ofport;
734 /* Add GARP for new vif. */
736 for (i = 0; i < binding_rec->n_mac; i++) {
737 struct lport_addresses laddrs;
738 if (!extract_lsp_addresses(binding_rec->mac[i], &laddrs)
739 || !laddrs.n_ipv4_addrs) {
743 struct garp_data *garp = xmalloc(sizeof *garp);
744 garp->ea = laddrs.ea;
745 garp->ipv4 = laddrs.ipv4_addrs[0].addr;
746 garp->announce_time = time_msec() + 1000;
748 garp->ofport = ofport;
749 shash_add(&send_garp_data, binding_rec->logical_port, garp);
751 destroy_lport_addresses(&laddrs);
756 /* Remove a vif from GARP announcements. */
758 send_garp_delete(const char *lport)
760 struct garp_data *garp = shash_find_and_delete(&send_garp_data, lport);
765 send_garp(struct garp_data *garp, long long int current_time)
767 if (current_time < garp->announce_time) {
768 return garp->announce_time;
771 /* Compose a GARP request packet. */
772 uint64_t packet_stub[128 / 8];
773 struct dp_packet packet;
774 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
775 compose_arp(&packet, ARP_OP_REQUEST, garp->ea, eth_addr_zero,
776 true, garp->ipv4, garp->ipv4);
778 /* Compose actions. The garp request is output on localnet ofport. */
779 uint64_t ofpacts_stub[4096 / 8];
780 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
781 enum ofp_version version = rconn_get_version(swconn);
782 ofpact_put_OUTPUT(&ofpacts)->port = garp->ofport;
784 struct ofputil_packet_out po = {
785 .packet = dp_packet_data(&packet),
786 .packet_len = dp_packet_size(&packet),
787 .buffer_id = UINT32_MAX,
788 .in_port = OFPP_CONTROLLER,
789 .ofpacts = ofpacts.data,
790 .ofpacts_len = ofpacts.size,
792 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
793 queue_msg(ofputil_encode_packet_out(&po, proto));
794 dp_packet_uninit(&packet);
795 ofpbuf_uninit(&ofpacts);
797 /* Set the next announcement. At most 5 announcements are sent for a
799 if (garp->backoff < 16) {
801 garp->announce_time = current_time + garp->backoff * 1000;
803 garp->announce_time = LLONG_MAX;
805 return garp->announce_time;
808 /* Get localnet vifs, and ofport for localnet patch ports. */
810 get_localnet_vifs(const struct ovsrec_bridge *br_int,
811 const char *this_chassis_id,
812 const struct lport_index *lports,
813 struct hmap *local_datapaths,
814 struct sset *localnet_vifs,
815 struct simap *localnet_ofports)
817 for (int i = 0; i < br_int->n_ports; i++) {
818 const struct ovsrec_port *port_rec = br_int->ports[i];
819 if (!strcmp(port_rec->name, br_int->name)) {
822 const char *chassis_id = smap_get(&port_rec->external_ids,
824 if (chassis_id && !strcmp(chassis_id, this_chassis_id)) {
827 const char *localnet = smap_get(&port_rec->external_ids,
828 "ovn-localnet-port");
829 for (int j = 0; j < port_rec->n_interfaces; j++) {
830 const struct ovsrec_interface *iface_rec = port_rec->interfaces[j];
831 if (!iface_rec->n_ofport) {
835 int64_t ofport = iface_rec->ofport[0];
836 if (ofport < 1 || ofport > ofp_to_u16(OFPP_MAX)) {
839 simap_put(localnet_ofports, localnet, ofport);
842 const char *iface_id = smap_get(&iface_rec->external_ids,
847 const struct sbrec_port_binding *pb
848 = lport_lookup_by_name(lports, iface_id);
852 struct local_datapath *ld
853 = get_local_datapath(local_datapaths,
854 pb->datapath->tunnel_key);
855 if (ld && ld->localnet_port) {
856 sset_add(localnet_vifs, iface_id);
865 poll_timer_wait_until(send_garp_time);
869 send_garp_run(const struct ovsrec_bridge *br_int, const char *chassis_id,
870 const struct lport_index *lports,
871 struct hmap *local_datapaths)
873 struct sset localnet_vifs = SSET_INITIALIZER(&localnet_vifs);
874 struct simap localnet_ofports = SIMAP_INITIALIZER(&localnet_ofports);
876 get_localnet_vifs(br_int, chassis_id, lports, local_datapaths,
877 &localnet_vifs, &localnet_ofports);
879 /* For deleted ports, remove from send_garp_data. */
880 struct shash_node *iter, *next;
881 SHASH_FOR_EACH_SAFE (iter, next, &send_garp_data) {
882 if (!sset_contains(&localnet_vifs, iter->name)) {
883 send_garp_delete(iter->name);
887 /* Update send_garp_data. */
888 const char *iface_id;
889 SSET_FOR_EACH (iface_id, &localnet_vifs) {
890 const struct sbrec_port_binding *pb = lport_lookup_by_name(lports,
893 send_garp_update(pb, &localnet_ofports, local_datapaths);
897 /* Send GARPs, and update the next announcement. */
898 long long int current_time = time_msec();
899 send_garp_time = LLONG_MAX;
900 SHASH_FOR_EACH (iter, &send_garp_data) {
901 long long int next_announce = send_garp(iter->data, current_time);
902 if (send_garp_time > next_announce) {
903 send_garp_time = next_announce;
906 sset_destroy(&localnet_vifs);
907 simap_destroy(&localnet_ofports);
911 reload_metadata(struct ofpbuf *ofpacts, const struct match *md)
913 enum mf_field_id md_fields[] = {
914 #if FLOW_N_REGS == 16
936 for (size_t i = 0; i < ARRAY_SIZE(md_fields); i++) {
937 const struct mf_field *field = mf_from_id(md_fields[i]);
938 if (!mf_is_all_wild(field, &md->wc)) {
939 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
941 sf->flow_has_vlan = false;
942 mf_get_value(field, &md->flow, &sf->value);
943 memset(&sf->mask, 0xff, field->n_bytes);
949 pinctrl_handle_na(const struct flow *ip_flow,
950 const struct match *md,
951 struct ofpbuf *userdata)
953 /* This action only works for IPv6 ND packets, and the switch should only
954 * send us ND packets this way, but check here just to be sure. */
955 if (!is_nd(ip_flow, NULL)) {
956 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
957 VLOG_WARN_RL(&rl, "NA action on non-ND packet");
961 enum ofp_version version = rconn_get_version(swconn);
962 enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
964 uint64_t packet_stub[128 / 8];
965 struct dp_packet packet;
966 dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
968 ovs_be32 ipv6_src[4], ipv6_dst[4];
969 memcpy(ipv6_dst, &ip_flow->ipv6_src, sizeof ipv6_src);
970 memcpy(ipv6_src, &ip_flow->nd_target, sizeof ipv6_dst);
972 /* xxx These flags are not exactly correct. Look at section 7.2.4
973 * xxx of RFC 4861. For example, we need to set ND_RSO_ROUTER for
974 * xxx router's interfaces and ND_RSO_SOLICITED only if it was
977 ip_flow->dl_dst, ip_flow->dl_src,
979 htonl(ND_RSO_SOLICITED | ND_RSO_OVERRIDE));
981 /* Reload previous packet metadata. */
982 uint64_t ofpacts_stub[4096 / 8];
983 struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
984 reload_metadata(&ofpacts, md);
986 enum ofperr error = ofpacts_pull_openflow_actions(userdata, userdata->size,
989 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
990 VLOG_WARN_RL(&rl, "failed to parse actions for 'na' (%s)",
991 ofperr_to_string(error));
995 struct ofputil_packet_out po = {
996 .packet = dp_packet_data(&packet),
997 .packet_len = dp_packet_size(&packet),
998 .buffer_id = UINT32_MAX,
999 .in_port = OFPP_CONTROLLER,
1000 .ofpacts = ofpacts.data,
1001 .ofpacts_len = ofpacts.size,
1004 queue_msg(ofputil_encode_packet_out(&po, proto));
1007 dp_packet_uninit(&packet);
1008 ofpbuf_uninit(&ofpacts);