[ovs-dev] [PATCH 5/8] nsh: userland support for network service index
pritesh
pritesh.kothari at cisco.com
Fri Sep 20 08:04:22 UTC 2013
Support for nsh service index (nsi) is added, mainly incoming
nsi in a flow can be matched and appropriate action can be
taken on the flow based on it.
Signed-off-by: pritesh <pritesh.kothari at cisco.com>
diff --git a/lib/flow.c b/lib/flow.c
index 452f338..ec5bf01 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -545,6 +545,8 @@ flow_tun_flag_to_string(uint32_t flags)
return "key";
case FLOW_TNL_F_NSP:
return "nsp";
+ case FLOW_TNL_F_NSI:
+ return "nsi";
default:
return NULL;
}
diff --git a/lib/flow.h b/lib/flow.h
index e59c7bd..ac2bbd0 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -57,6 +57,7 @@ BUILD_ASSERT_DECL(FLOW_NW_FRAG_LATER == NX_IP_FRAG_LATER);
#define FLOW_TNL_F_CSUM (1 << 1)
#define FLOW_TNL_F_KEY (1 << 2)
#define FLOW_TNL_F_NSP (1 << 3)
+#define FLOW_TNL_F_NSI (1 << 4)
const char *flow_tun_flag_to_string(uint32_t flags);
@@ -68,6 +69,7 @@ struct flow_tnl {
uint16_t flags;
uint8_t ip_tos;
uint8_t ip_ttl;
+ uint8_t nsi;
};
/* Unfortunately, a "struct flow" sometimes has to handle OpenFlow port
diff --git a/lib/match.c b/lib/match.c
index 6ebe2f3..f6957a1 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -77,6 +77,9 @@ match_wc_init(struct match *match, const struct flow *flow)
if (flow->tunnel.flags & FLOW_TNL_F_NSP) {
memset(&wc->masks.tunnel.nsp, 0xff, sizeof wc->masks.tunnel.nsp);
}
+ if (flow->tunnel.flags & FLOW_TNL_F_NSI) {
+ memset(&wc->masks.tunnel.nsi, 0xff, sizeof wc->masks.tunnel.nsi);
+ }
memset(&wc->masks.tunnel.ip_src, 0xff, sizeof wc->masks.tunnel.ip_src);
memset(&wc->masks.tunnel.ip_dst, 0xff, sizeof wc->masks.tunnel.ip_dst);
memset(&wc->masks.tunnel.flags, 0xff, sizeof wc->masks.tunnel.flags);
@@ -90,6 +93,10 @@ match_wc_init(struct match *match, const struct flow *flow)
memset(&wc->masks.tunnel.nsp, 0xff, sizeof wc->masks.tunnel.nsp);
}
+ if (flow->tunnel.nsi) {
+ memset(&wc->masks.tunnel.nsi, 0xff, sizeof wc->masks.tunnel.nsi);
+ }
+
memset(&wc->masks.metadata, 0xff, sizeof wc->masks.metadata);
memset(&wc->masks.in_port, 0xff, sizeof wc->masks.in_port);
memset(&wc->masks.vlan_tci, 0xff, sizeof wc->masks.vlan_tci);
@@ -741,6 +748,19 @@ match_set_nsp(struct match *match, ovs_be32 nsp)
match_set_nsp_masked(match, nsp, htonl(UINT32_MAX));
}
+void
+match_set_nsi_masked(struct match *match, uint8_t nsi, uint8_t mask)
+{
+ match->wc.masks.tunnel.nsi = mask;
+ match->flow.tunnel.nsi = nsi & mask;
+}
+
+void
+match_set_nsi(struct match *match, uint8_t nsi)
+{
+ match_set_nsi_masked(match, nsi, UINT8_MAX);
+}
+
/* Returns true if 'a' and 'b' wildcard the same fields and have the same
* values for fixed fields, otherwise false. */
bool
@@ -841,6 +861,18 @@ format_flow_tunnel(struct ds *s, const struct match *match)
break;
}
+ switch (wc->masks.tunnel.nsi) {
+ case 0:
+ break;
+ case UINT8_MAX:
+ ds_put_format(s, "nsi=%"PRIu8",", tnl->nsi);
+ break;
+ default:
+ ds_put_format(s, "nsi=%"PRIu8"/%"PRIu8",",
+ tnl->nsi, wc->masks.tunnel.nsi);
+ break;
+ }
+
format_ip_netmask(s, "tun_src", tnl->ip_src, wc->masks.tunnel.ip_src);
format_ip_netmask(s, "tun_dst", tnl->ip_dst, wc->masks.tunnel.ip_dst);
diff --git a/lib/match.h b/lib/match.h
index dbe13f1..fd17de6 100644
--- a/lib/match.h
+++ b/lib/match.h
@@ -122,6 +122,8 @@ void match_set_nd_target_masked(struct match *, const struct in6_addr *,
const struct in6_addr *);
void match_set_nsp(struct match *, ovs_be32 nsp);
void match_set_nsp_masked(struct match *, ovs_be32 nsp, ovs_be32 mask);
+void match_set_nsi_masked(struct match *match, uint8_t nsi, uint8_t mask);
+void match_set_nsi(struct match *match, uint8_t nsi);
bool match_equal(const struct match *, const struct match *);
uint32_t match_hash(const struct match *, uint32_t basis);
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 67ddd3e..8e11de0 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -711,6 +711,17 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
0, NULL,
OFPUTIL_P_OF10_NXM_ANY,
OFPUTIL_P_OF10_NXM_ANY,
+ }, {
+ MFF_NSI, "nsi", NULL,
+ MF_FIELD_SIZES(u8),
+ MFM_FULLY,
+ MFS_HEXADECIMAL,
+ MFP_NONE,
+ false,
+ 0, NULL,
+ 0, NULL,
+ OFPUTIL_P_OF10_NXM_ANY,
+ OFPUTIL_P_OF10_NXM_ANY,
},
};
@@ -842,6 +853,8 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
return !wc->masks.tunnel.tun_id;
case MFF_NSP:
return !wc->masks.tunnel.nsp;
+ case MFF_NSI:
+ return !wc->masks.tunnel.nsi;
case MFF_METADATA:
return !wc->masks.metadata;
case MFF_IN_PORT:
@@ -1089,6 +1102,7 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
case MFF_ND_SLL:
case MFF_ND_TLL:
case MFF_NSP:
+ case MFF_NSI:
return true;
case MFF_IN_PORT_OXM: {
@@ -1320,6 +1334,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
value->be32 = flow->tunnel.nsp;
break;
+ case MFF_NSI:
+ value->u8 = flow->tunnel.nsi;
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -1516,6 +1534,10 @@ mf_set_value(const struct mf_field *mf,
match_set_nsp(match, value->be32);
break;
+ case MFF_NSI:
+ match_set_nsi(match, value->u8);
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -1714,6 +1736,10 @@ mf_set_flow_value(const struct mf_field *mf,
flow->tunnel.nsp = value->be32;
break;
+ case MFF_NSI:
+ flow->tunnel.nsi = value->u8;
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -1921,6 +1947,10 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
match_set_nsp_masked(match, htonl(0), htonl(0));
break;
+ case MFF_NSI:
+ match_set_nsi_masked(match, 0, 0);
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -2089,6 +2119,10 @@ mf_set(const struct mf_field *mf,
match_set_nsp_masked(match, value->be32, mask->be32);
break;
+ case MFF_NSI:
+ match_set_nsi_masked(match, value->u8, mask->u8);
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -2209,6 +2243,7 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
case MFF_ND_SLL:
case MFF_ND_TLL:
case MFF_NSP:
+ case MFF_NSI:
break;
case MFF_IN_PORT_OXM:
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 4d1c3fb..666479d 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -138,6 +138,7 @@ enum mf_field_id {
/* Network Service Headers (NSH) Fields */
MFF_NSP, /* be32 */
+ MFF_NSI, /* u8 */
MFF_N_IDS
};
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 181977c..4a2ca52 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -44,6 +44,8 @@ VLOG_DEFINE_THIS_MODULE(netdev_vport);
#define VXLAN_DST_PORT 4789
#define LISP_DST_PORT 4341
+#define NSH_DST_PORT 9030
+
#define DEFAULT_TTL 64
struct netdev_vport {
@@ -349,6 +351,33 @@ parse_nsp(const struct smap *args, const char *name,
}
}
+static uint8_t
+parse_nsi(const struct smap *args, const char *name,
+ bool *present, bool *flow)
+{
+ const char *s;
+
+ *present = false;
+ *flow = false;
+
+ s = smap_get(args, name);
+ if (!s) {
+ s = smap_get(args, "nsi");
+ if (!s) {
+ return 0;
+ }
+ }
+
+ *present = true;
+
+ if (!strcmp(s, "flow")) {
+ *flow = true;
+ return 0;
+ } else {
+ return strtoul(s, NULL, 0);
+ }
+}
+
static int
set_tunnel_config(struct netdev *dev_, const struct smap *args)
{
@@ -456,6 +485,10 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
!strcmp(node->key, "in_nsp") ||
!strcmp(node->key, "out_nsp")) {
/* Handled separately below. */
+ } else if (!strcmp(node->key, "nsi") ||
+ !strcmp(node->key, "in_nsi") ||
+ !strcmp(node->key, "out_nsi")) {
+ /* Handled separately below. */
} else {
VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key);
}
@@ -532,6 +565,24 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
&tnl_cfg.out_nsp_present,
&tnl_cfg.out_nsp_flow);
+ tnl_cfg.in_nsi = parse_nsi(args, "in_nsi",
+ &tnl_cfg.in_nsi_present,
+ &tnl_cfg.in_nsi_flow);
+
+ tnl_cfg.out_nsi = parse_nsi(args, "out_nsi",
+ &tnl_cfg.out_nsi_present,
+ &tnl_cfg.out_nsi_flow);
+
+ if (tnl_cfg.dst_port == htons(NSH_DST_PORT)) {
+ /* Default nsh service index is 1, if lower packet is dropped */
+ if (!tnl_cfg.in_nsi) {
+ tnl_cfg.in_nsi = 1;
+ }
+ if (!tnl_cfg.out_nsi) {
+ tnl_cfg.out_nsi = 1;
+ }
+ }
+
ovs_mutex_lock(&dev->mutex);
dev->tnl_cfg = tnl_cfg;
netdev_vport_poll_notify(dev);
diff --git a/lib/netdev.h b/lib/netdev.h
index 36817f5..c23fe25 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -110,6 +110,14 @@ struct netdev_tunnel_config {
bool out_nsp_flow;
ovs_be32 out_nsp; /* outgoing NSH service path */
+ bool in_nsi_present;
+ bool in_nsi_flow;
+ uint8_t in_nsi; /* incoming NSH service index */
+
+ bool out_nsi_present;
+ bool out_nsi_flow;
+ uint8_t out_nsi; /* outgoing NSH service index */
+
bool in_key_present;
bool in_key_flow;
ovs_be64 in_key;
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 379c49b..d19b8ea 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -807,6 +807,7 @@ tunnel_key_attr_len(int type)
case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT: return 0;
case OVS_TUNNEL_KEY_ATTR_CSUM: return 0;
case OVS_TUNNEL_KEY_ATTR_NSP: return 4;
+ case OVS_TUNNEL_KEY_ATTR_NSI: return 1;
case __OVS_TUNNEL_KEY_ATTR_MAX:
return -1;
}
@@ -858,6 +859,10 @@ odp_tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
tun->nsp = nl_attr_get_be32(a);
tun->flags |= FLOW_TNL_F_NSP;
break;
+ case OVS_TUNNEL_KEY_ATTR_NSI:
+ tun->nsi = nl_attr_get_u8(a);
+ tun->flags |= FLOW_TNL_F_NSI;
+ break;
default:
/* Allow this to show up as unexpected, if there are unknown
* tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
@@ -904,6 +909,9 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key)
if (tun_key->flags & FLOW_TNL_F_NSP) {
nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_NSP, tun_key->nsp);
}
+ if (tun_key->flags & FLOW_TNL_F_NSI) {
+ nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_NSI, tun_key->nsi);
+ }
nl_msg_end_nested(a, tun_key_ofs);
}
@@ -931,6 +939,7 @@ odp_mask_attr_is_exact(const struct nlattr *ma)
if (tun_mask.flags == (FLOW_TNL_F_KEY
| FLOW_TNL_F_DONT_FRAGMENT
| FLOW_TNL_F_NSP
+ | FLOW_TNL_F_NSI
| FLOW_TNL_F_CSUM)) {
/* The flags are exact match, check the remaining fields. */
tun_mask.flags = 0xffff;
@@ -1016,11 +1025,13 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
odp_tun_key_from_attr(ma, &tun_mask);
ds_put_format(ds, "tun_id=%#"PRIx64"/%#"PRIx64
",nsp=%#"PRIx32"/%#"PRIx32
+ ",nsi=%"PRIu8"/%"PRIu8
",src="IP_FMT"/"IP_FMT",dst="IP_FMT"/"IP_FMT
",tos=%#"PRIx8"/%#"PRIx8",ttl=%"PRIu8"/%#"PRIx8
",flags(",
ntohll(tun_key.tun_id), ntohll(tun_mask.tun_id),
ntohl(tun_key.nsp), ntohl(tun_mask.nsp),
+ tun_key.nsi, tun_mask.nsi,
IP_ARGS(tun_key.ip_src), IP_ARGS(tun_mask.ip_src),
IP_ARGS(tun_key.ip_dst), IP_ARGS(tun_mask.ip_dst),
tun_key.ip_tos, tun_mask.ip_tos,
@@ -1037,10 +1048,10 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
ds_put_char(ds, ')');
} else {
ds_put_format(ds, "tun_id=0x%"PRIx64",nsp=0x%"PRIx32
- ",src="IP_FMT",dst="IP_FMT","
+ ",nsi=%"PRIu8",src="IP_FMT",dst="IP_FMT","
"tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
ntohll(tun_key.tun_id),
- ntohl(tun_key.nsp),
+ ntohl(tun_key.nsp), tun_key.nsi,
IP_ARGS(tun_key.ip_src),
IP_ARGS(tun_key.ip_dst),
tun_key.ip_tos, tun_key.ip_ttl);
@@ -1582,14 +1593,15 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
struct flow_tnl tun_key, tun_key_mask;
unsigned long long tun_id_mask;
uint32_t nsp, nsp_mask;
+ int nsi, nsi_mask;
int n = -1;
if (mask && sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF]/%llx,"
- "nsp=%"PRIx32"/%"PRIx32
+ "nsp=%"PRIx32"/%"PRIx32",nsi=%i/%i,"
"src="IP_SCAN_FMT"/"IP_SCAN_FMT",dst="IP_SCAN_FMT
"/"IP_SCAN_FMT",tos=%i/%i,ttl=%i/%i,flags%n",
tun_id_s, &tun_id_mask,
- &nsp, &nsp_mask,
+ &nsp, &nsp_mask, &nsi, &nsi_mask,
IP_SCAN_ARGS(&tun_key.ip_src),
IP_SCAN_ARGS(&tun_key_mask.ip_src),
IP_SCAN_ARGS(&tun_key.ip_dst),
@@ -1603,6 +1615,8 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
tun_key_mask.tun_id = htonll(tun_id_mask);
tun_key.nsp = htonl(nsp);
tun_key_mask.nsp = htonl(nsp_mask);
+ tun_key.nsi = nsi;
+ tun_key_mask.nsi = nsi_mask;
tun_key.ip_tos = tos;
tun_key_mask.ip_tos = tos_mask;
tun_key.ip_ttl = ttl;
@@ -1625,10 +1639,10 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
}
return n;
} else if (sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
- "nsp=%"PRIx32","
+ "nsp=%"PRIx32",nsi=%i,"
"src="IP_SCAN_FMT",dst="IP_SCAN_FMT
",tos=%i,ttl=%i,flags%n", tun_id_s,
- &tun_key.nsp,
+ &tun_key.nsp, &nsi,
IP_SCAN_ARGS(&tun_key.ip_src),
IP_SCAN_ARGS(&tun_key.ip_dst), &tos, &ttl,
&n) > 0 && n > 0) {
@@ -1637,6 +1651,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0));
tun_key.nsp = htonl(tun_key.nsp);
+ tun_key.nsi = nsi;
tun_key.ip_tos = tos;
tun_key.ip_ttl = ttl;
res = parse_flags(&s[n], flow_tun_flag_to_string, &flags);
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 4642b17..11f92a8 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -65,6 +65,7 @@ int odp_actions_from_string(const char *, const struct simap *port_names,
* - OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT 0 -- 4 4
* - OVS_TUNNEL_KEY_ATTR_CSUM 0 -- 4 4
* - OVS_TUNNEL_KEY_ATTR_NSP 4 -- 4 8
+ * - OVS_TUNNEL_KEY_ATTR_NSI 1 3 4 8
* OVS_KEY_ATTR_IN_PORT 4 -- 4 8
* OVS_KEY_ATTR_SKB_MARK 4 -- 4 8
* OVS_KEY_ATTR_ETHERNET 12 -- 4 16
@@ -76,7 +77,7 @@ int odp_actions_from_string(const char *, const struct simap *port_names,
* OVS_KEY_ATTR_ICMPV6 2 2 4 8
* OVS_KEY_ATTR_ND 28 -- 4 32
* ----------------------------------------------------------
- * total 216
+ * total 224
*
* We include some slack space in case the calculation isn't quite right or we
* add another field and forget to adjust this value.
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 35aa98b..dac5cfd 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -41,10 +41,12 @@ struct tnl_match {
ovs_be32 ip_dst;
odp_port_t odp_port;
uint32_t pkt_mark;
+ uint8_t in_nsi;
bool in_key_flow;
bool in_nsp_flow;
bool ip_src_flow;
bool ip_dst_flow;
+ bool in_nsi_flow;
};
struct tnl_port {
@@ -103,6 +105,7 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev,
tnl_port->match.in_key = cfg->in_key;
tnl_port->match.in_nsp = cfg->in_nsp;
+ tnl_port->match.in_nsi = cfg->in_nsi;
tnl_port->match.ip_src = cfg->ip_src;
tnl_port->match.ip_dst = cfg->ip_dst;
tnl_port->match.ip_src_flow = cfg->ip_src_flow;
@@ -110,6 +113,7 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev,
tnl_port->match.pkt_mark = cfg->ipsec ? IPSEC_MARK : 0;
tnl_port->match.in_key_flow = cfg->in_key_flow;
tnl_port->match.in_nsp_flow = cfg->in_nsp_flow;
+ tnl_port->match.in_nsi_flow = cfg->in_nsi_flow;
tnl_port->match.odp_port = odp_port;
existing_port = tnl_find_exact(&tnl_port->match);
@@ -330,6 +334,10 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
flow->tunnel.nsp = cfg->out_nsp;
}
+ if (!cfg->out_nsi_flow) {
+ flow->tunnel.nsi = cfg->out_nsi;
+ }
+
if (cfg->ttl_inherit && is_ip_any(flow)) {
wc->masks.nw_ttl = 0xff;
flow->tunnel.ip_ttl = flow->nw_ttl;
@@ -358,6 +366,7 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
flow->tunnel.flags = (cfg->dont_fragment ? FLOW_TNL_F_DONT_FRAGMENT : 0)
| (cfg->csum ? FLOW_TNL_F_CSUM : 0)
| (cfg->out_nsp_present ? FLOW_TNL_F_NSP : 0)
+ | (cfg->out_nsi_present ? FLOW_TNL_F_NSI : 0)
| (cfg->out_key_present ? FLOW_TNL_F_KEY : 0);
if (pre_flow_str) {
@@ -428,22 +437,35 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
bool in_key_flow;
bool ip_dst_flow;
bool in_nsp_flow;
+ bool in_nsi_flow;
enum ip_src_type ip_src;
};
static const struct tnl_match_pattern patterns[] = {
- { false, false, false, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
- { false, false, false, IP_SRC_ANY }, /* remote_ip, in_key. */
- { true, false, false, IP_SRC_EXACT }, /* remote_ip, local_ip. */
- { true, false, false, IP_SRC_ANY }, /* remote_ip. */
- { true, true, false, IP_SRC_ANY }, /* Flow-based remote. */
- { true, true, false, IP_SRC_FLOW }, /* Flow-based everything. */
- { false, false, true, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
- { false, false, true, IP_SRC_ANY }, /* remote_ip, in_key. */
- { true, false, true, IP_SRC_EXACT }, /* remote_ip, local_ip. */
- { true, false, true, IP_SRC_ANY }, /* remote_ip. */
- { true, true, true, IP_SRC_ANY }, /* Flow-based remote. */
- { true, true, true, IP_SRC_FLOW }, /* Flow-based everything. */
+ { false, false, false, false, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
+ { false, false, false, false, IP_SRC_ANY }, /* remote_ip, in_key. */
+ { true, false, false, false, IP_SRC_EXACT }, /* remote_ip, local_ip. */
+ { true, false, false, false, IP_SRC_ANY }, /* remote_ip. */
+ { true, true, false, false, IP_SRC_ANY }, /* Flow-based remote. */
+ { true, true, false, false, IP_SRC_FLOW }, /* Flow-based everything. */
+ { false, false, true, false, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
+ { false, false, true, false, IP_SRC_ANY }, /* remote_ip, in_key. */
+ { true, false, true, false, IP_SRC_EXACT }, /* remote_ip, local_ip. */
+ { true, false, true, false, IP_SRC_ANY }, /* remote_ip. */
+ { true, true, true, false, IP_SRC_ANY }, /* Flow-based remote. */
+ { true, true, true, false, IP_SRC_FLOW }, /* Flow-based everything. */
+ { false, false, false, true, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
+ { false, false, false, true, IP_SRC_ANY }, /* remote_ip, in_key. */
+ { true, false, false, true, IP_SRC_EXACT }, /* remote_ip, local_ip. */
+ { true, false, false, true, IP_SRC_ANY }, /* remote_ip. */
+ { true, true, false, true, IP_SRC_ANY }, /* Flow-based remote. */
+ { true, true, false, true, IP_SRC_FLOW }, /* Flow-based everything. */
+ { false, false, true, true, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
+ { false, false, true, true, IP_SRC_ANY }, /* remote_ip, in_key. */
+ { true, false, true, true, IP_SRC_EXACT }, /* remote_ip, local_ip. */
+ { true, false, true, true, IP_SRC_ANY }, /* remote_ip. */
+ { true, true, true, true, IP_SRC_ANY }, /* Flow-based remote. */
+ { true, true, true, true, IP_SRC_FLOW }, /* Flow-based everything. */
};
const struct tnl_match_pattern *p;
@@ -462,6 +484,9 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
match.in_nsp_flow = p->in_nsp_flow;
match.in_nsp = p->in_nsp_flow ? 0 : flow->tunnel.nsp;
+ match.in_nsi_flow = p->in_nsi_flow;
+ match.in_nsi = p->in_nsi_flow ? 1 : flow->tunnel.nsi;
+
match.ip_dst_flow = p->ip_dst_flow;
match.ip_dst = p->ip_dst_flow ? 0 : flow->tunnel.ip_src;
@@ -502,6 +527,12 @@ tnl_match_fmt(const struct tnl_match *match, struct ds *ds)
ds_put_format(ds, ", nsp=%#"PRIx32, ntohl(match->in_nsp));
}
+ if (match->in_nsi_flow) {
+ ds_put_cstr(ds, ", nsi=flow");
+ } else {
+ ds_put_format(ds, ", nsi=%"PRIu8, match->in_nsi);
+ }
+
ds_put_format(ds, ", dp port=%"PRIu32, match->odp_port);
ds_put_format(ds, ", pkt mark=%"PRIu32, match->pkt_mark);
}
@@ -558,6 +589,19 @@ tnl_port_fmt(const struct tnl_port *tnl_port) OVS_REQ_RDLOCK(rwlock)
}
}
+ if (cfg->out_nsi != cfg->in_nsi ||
+ cfg->out_nsi_present != cfg->in_nsi_present ||
+ cfg->out_nsi_flow != cfg->in_nsi_flow) {
+ ds_put_cstr(&ds, ", out_nsi=");
+ if (!cfg->out_nsi_present) {
+ ds_put_cstr(&ds, "none");
+ } else if (cfg->out_nsi_flow) {
+ ds_put_cstr(&ds, "flow");
+ } else {
+ ds_put_format(&ds, "%"PRIu8, cfg->out_nsi);
+ }
+ }
+
if (cfg->ttl_inherit) {
ds_put_cstr(&ds, ", ttl=inherit");
} else {
--
1.7.9.5
More information about the dev
mailing list