/*
- * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2014, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "route-table.h"
#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/rtnetlink.h>
#include "ovs-router.h"
#include "packets.h"
#include "rtnetlink.h"
+#include "tnl-ports.h"
#include "openvswitch/vlog.h"
+/* Linux 2.6.36 added RTA_MARK, so define it just in case we're building with
+ * old headers. (We can't test for it with #ifdef because it's an enum.) */
+#define RTA_MARK 16
+
VLOG_DEFINE_THIS_MODULE(route_table);
struct route_data {
/* Copied from struct rtmsg. */
unsigned char rtm_dst_len;
+ bool local;
/* Extracted from Netlink attributes. */
struct in6_addr rta_dst; /* 0 if missing. */
route_table_reset(void)
{
struct nl_dump dump;
- struct rtgenmsg *rtmsg;
+ struct rtgenmsg *rtgenmsg;
uint64_t reply_stub[NL_DUMP_BUFSIZE / 8];
struct ofpbuf request, reply, buf;
ofpbuf_init(&request, 0);
- nl_msg_put_nlmsghdr(&request, sizeof *rtmsg, RTM_GETROUTE, NLM_F_REQUEST);
+ nl_msg_put_nlmsghdr(&request, sizeof *rtgenmsg, RTM_GETROUTE,
+ NLM_F_REQUEST);
- rtmsg = ofpbuf_put_zeros(&request, sizeof *rtmsg);
- rtmsg->rtgen_family = AF_UNSPEC;
+ rtgenmsg = ofpbuf_put_zeros(&request, sizeof *rtgenmsg);
+ rtgenmsg->rtgen_family = AF_UNSPEC;
nl_dump_start(&dump, NETLINK_ROUTE, &request);
ofpbuf_uninit(&request);
}
change->nlmsg_type = nlmsg->nlmsg_type;
change->rd.rtm_dst_len = rtm->rtm_dst_len + (ipv4 ? 96 : 0);
+ change->rd.local = rtm->rtm_type == RTN_LOCAL;
if (attrs[RTA_OIF]) {
rta_oif = nl_attr_get_u32(attrs[RTA_OIF]);
if (change->relevant && change->nlmsg_type == RTM_NEWROUTE) {
const struct route_data *rd = &change->rd;
- ovs_router_insert(&rd->rta_dst, rd->rtm_dst_len,
- rd->ifname, &rd->rta_gw);
+ ovs_router_insert(rd->mark, &rd->rta_dst, rd->rtm_dst_len,
+ rd->local, rd->ifname, &rd->rta_gw);
}
}
static void
-name_table_change(const struct rtnetlink_change *change OVS_UNUSED,
+name_table_change(const struct rtnetlink_change *change,
void *aux OVS_UNUSED)
{
/* Changes to interface status can cause routing table changes that some
* versions of the linux kernel do not advertise for some reason. */
route_table_valid = false;
+
+ if (change && change->nlmsg_type == RTM_DELLINK) {
+ if (change->ifname) {
+ tnl_port_map_delete_ipdev(change->ifname);
+ }
+ }
}