Skip to content

Commit

Permalink
ofproto-dpif-xlate: makes OVS native tunneling honor tunnel-specified…
Browse files Browse the repository at this point in the history
… source addresses

It makes OVS native tunneling honor tunnel-specified source addresses,
in the same way that Linux kernel tunneling honors them.

This patch made valid tun_src specified by flow-action can be used for
tunnel_src of packet. add a "local" property for a route entry and enhance
the priority of local route higher than user route.
Like the kernel space when lookup the route, if there are tun_src specified
by flow-action or port options. Check the tun_src wheather is a local
address, then lookup the route.

Signed-off-by: wenxu <wenxu@ucloud.cn>
Signed-off-by: frank.zeng <frank.zeng@ucloud.cn>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
wenxu authored and blp committed Apr 18, 2018
1 parent 49b9cad commit 8e4e458
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 10 deletions.
36 changes: 29 additions & 7 deletions lib/ovs-router.c
Expand Up @@ -66,6 +66,7 @@ struct ovs_router_entry {
struct in6_addr src_addr;
uint8_t plen;
uint8_t priority;
bool local;
uint32_t mark;
};

Expand Down Expand Up @@ -110,13 +111,28 @@ ovs_router_lookup(uint32_t mark, const struct in6_addr *ip6_dst,
const struct cls_rule *cr;
struct flow flow = {.ipv6_dst = *ip6_dst, .pkt_mark = mark};

if (src && ipv6_addr_is_set(src)) {
const struct cls_rule *cr_src;
struct flow flow_src = {.ipv6_dst = *src, .pkt_mark = mark};

cr_src = classifier_lookup(&cls, OVS_VERSION_MAX, &flow_src, NULL);
if (cr_src) {
struct ovs_router_entry *p_src = ovs_router_entry_cast(cr_src);
if (!p_src->local) {
return false;
}
} else {
return false;
}
}

cr = classifier_lookup(&cls, OVS_VERSION_MAX, &flow, NULL);
if (cr) {
struct ovs_router_entry *p = ovs_router_entry_cast(cr);

ovs_strlcpy(output_bridge, p->output_bridge, IFNAMSIZ);
*gw = p->gw;
if (src) {
if (src && !ipv6_addr_is_set(src)) {
*src = p->src_addr;
}
return true;
Expand Down Expand Up @@ -197,7 +213,7 @@ get_src_addr(const struct in6_addr *ip6_dst,
}

static int
ovs_router_insert__(uint32_t mark, uint8_t priority,
ovs_router_insert__(uint32_t mark, uint8_t priority, bool local,
const struct in6_addr *ip6_dst,
uint8_t plen, const char output_bridge[],
const struct in6_addr *gw)
Expand All @@ -217,6 +233,7 @@ ovs_router_insert__(uint32_t mark, uint8_t priority,
p->mark = mark;
p->nw_addr = match.flow.ipv6_dst;
p->plen = plen;
p->local = local;
p->priority = priority;
err = get_src_addr(ip6_dst, output_bridge, &p->src_addr);
if (err && ipv6_addr_is_set(gw)) {
Expand Down Expand Up @@ -249,10 +266,12 @@ ovs_router_insert__(uint32_t mark, uint8_t priority,

void
ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen,
const char output_bridge[], const struct in6_addr *gw)
bool local, const char output_bridge[],
const struct in6_addr *gw)
{
if (use_system_routing_table) {
ovs_router_insert__(mark, plen, ip_dst, plen, output_bridge, gw);
uint8_t priority = local ? plen + 64 : plen;
ovs_router_insert__(mark, priority, local, ip_dst, plen, output_bridge, gw);
}
}

Expand Down Expand Up @@ -360,7 +379,7 @@ ovs_router_add(struct unixctl_conn *conn, int argc,
}
}

err = ovs_router_insert__(mark, plen + 32, &ip6, plen, argv[2], &gw6);
err = ovs_router_insert__(mark, plen + 32, false, &ip6, plen, argv[2], &gw6);
if (err) {
unixctl_command_reply_error(conn, "Error while inserting route.");
} else {
Expand Down Expand Up @@ -409,7 +428,7 @@ ovs_router_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
ds_put_format(&ds, "Route Table:\n");
CLS_FOR_EACH(rt, cr, &cls) {
uint8_t plen;
if (rt->priority == rt->plen) {
if (rt->priority == rt->plen || rt->local) {
ds_put_format(&ds, "Cached: ");
} else {
ds_put_format(&ds, "User: ");
Expand All @@ -431,6 +450,9 @@ ovs_router_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
}
ds_put_format(&ds, " SRC ");
ipv6_format_mapped(&rt->src_addr, &ds);
if (rt->local) {
ds_put_format(&ds, " local");
}
ds_put_format(&ds, "\n");
}
unixctl_command_reply(conn, ds_cstr(&ds));
Expand All @@ -441,7 +463,7 @@ static void
ovs_router_lookup_cmd(struct unixctl_conn *conn, int argc,
const char *argv[], void *aux OVS_UNUSED)
{
struct in6_addr gw, src;
struct in6_addr gw, src = in6addr_any;
char iface[IFNAMSIZ];
struct in6_addr ip6;
unsigned int plen;
Expand Down
2 changes: 1 addition & 1 deletion lib/ovs-router.h
Expand Up @@ -31,7 +31,7 @@ bool ovs_router_lookup(uint32_t mark, const struct in6_addr *ip_dst,
struct in6_addr *src, struct in6_addr *gw);
void ovs_router_init(void);
void ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst,
uint8_t plen,
uint8_t plen, bool local,
const char output_bridge[], const struct in6_addr *gw);
void ovs_router_flush(void);

Expand Down
4 changes: 3 additions & 1 deletion lib/route-table.c
Expand Up @@ -47,6 +47,7 @@ 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. */
Expand Down Expand Up @@ -245,6 +246,7 @@ route_table_parse(struct ofpbuf *buf, struct route_table_msg *change)
}
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]);

Expand Down Expand Up @@ -307,7 +309,7 @@ route_table_handle_msg(const struct route_table_msg *change)
const struct route_data *rd = &change->rd;

ovs_router_insert(rd->mark, &rd->rta_dst, rd->rtm_dst_len,
rd->ifname, &rd->rta_gw);
rd->local, rd->ifname, &rd->rta_gw);
}
}

Expand Down
2 changes: 1 addition & 1 deletion ofproto/ofproto-dpif-sflow.c
Expand Up @@ -474,7 +474,7 @@ sflow_choose_agent_address(const char *agent_device,
*/
ip = ss_get_address(&ss);

struct in6_addr src, gw;
struct in6_addr gw, src = in6addr_any;
char name[IFNAMSIZ];
if (ovs_router_lookup(0, &ip, name, &src, &gw)) {
goto success;
Expand Down
4 changes: 4 additions & 0 deletions ofproto/ofproto-dpif-xlate.c
Expand Up @@ -3320,6 +3320,10 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
/* Backup flow & base_flow data. */
memcpy(&old_base_flow, &ctx->base_flow, sizeof old_base_flow);
memcpy(&old_flow, &ctx->xin->flow, sizeof old_flow);

if (flow->tunnel.ip_src) {
in6_addr_set_mapped_ipv4(&s_ip6, flow->tunnel.ip_src);
}

err = tnl_route_lookup_flow(ctx, flow, &d_ip6, &s_ip6, &out_dev);
if (err) {
Expand Down

0 comments on commit 8e4e458

Please sign in to comment.