Skip to content

Commit

Permalink
route-table: Handle route updates more robustly.
Browse files Browse the repository at this point in the history
The kernel does not broadcast rtnetlink route messages in all cases
one would expect.  This can cause stale entires to end up in the
route table which may cause incorrect results for
route_table_get_ifindex() queries.  This commit causes rtnetlink
route messages to dump the entire route table on the next
route_table_get_ifindex() query.
  • Loading branch information
ejj committed Jan 14, 2011
1 parent db2dede commit f0e167f
Showing 1 changed file with 22 additions and 26 deletions.
48 changes: 22 additions & 26 deletions lib/route-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ static unsigned int register_count = 0;
static struct rtnetlink *rtn = NULL;
static struct route_table_msg rtmsg;
static struct rtnetlink_notifier notifier;

static bool route_table_valid = false;
static struct hmap route_map;

static int route_table_reset(void);
static void route_table_handle_msg(const struct route_table_msg *);
static bool route_table_parse(struct ofpbuf *, struct route_table_msg *);
static void route_table_change(const struct route_table_msg *, void *);
static struct route_node *route_node_lookup(const struct route_data *);
Expand All @@ -86,6 +89,10 @@ route_table_get_ifindex(ovs_be32 ip_, int *ifindex)

*ifindex = 0;

if (!route_table_valid) {
route_table_reset();
}

rn = route_node_lookup_by_ip(ip);

if (rn) {
Expand Down Expand Up @@ -173,6 +180,7 @@ route_table_reset(void)
static struct nl_sock *rtnl_sock;

route_map_clear();
route_table_valid = true;

error = nl_sock_create(NETLINK_ROUTE, 0, 0, 0, &rtnl_sock);
if (error) {
Expand All @@ -194,7 +202,7 @@ route_table_reset(void)
struct route_table_msg msg;

if (route_table_parse(&reply, &msg)) {
route_table_change(&msg, NULL);
route_table_handle_msg(&msg);
}
}

Expand Down Expand Up @@ -260,35 +268,23 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change)
}

static void
route_table_change(const struct route_table_msg *change, void *aux OVS_UNUSED)
route_table_change(const struct route_table_msg *change OVS_UNUSED,
void *aux OVS_UNUSED)
{
if (!change) {
VLOG_DBG_RL(&rl, "received NULL change message");
route_table_reset();
} else if (!change->relevant) {
VLOG_DBG_RL(&rl, "ignoring irrelevant change message");
} else if (change->nlmsg_type == RTM_NEWROUTE) {
if (!route_node_lookup(&change->rd)) {
struct route_node *rn;

rn = xzalloc(sizeof *rn);
memcpy(&rn->rd, &change->rd, sizeof change->rd);

hmap_insert(&route_map, &rn->node, hash_route_data(&rn->rd));
} else {
VLOG_DBG_RL(&rl, "skipping insertion of duplicate route entry");
}
} else if (change->nlmsg_type == RTM_DELROUTE) {
route_table_valid = false;
}

static void
route_table_handle_msg(const struct route_table_msg *change)
{
if (change->relevant && change->nlmsg_type == RTM_NEWROUTE &&
!route_node_lookup(&change->rd)) {
struct route_node *rn;

rn = route_node_lookup(&change->rd);
rn = xzalloc(sizeof *rn);
memcpy(&rn->rd, &change->rd, sizeof change->rd);

if (rn) {
hmap_remove(&route_map, &rn->node);
free(rn);
} else {
VLOG_DBG_RL(&rl, "skipping deletion of non-existent route entry");
}
hmap_insert(&route_map, &rn->node, hash_route_data(&rn->rd));
}
}

Expand Down

0 comments on commit f0e167f

Please sign in to comment.