Skip to content

Commit

Permalink
Support packet metadata marking for logical port traffic.
Browse files Browse the repository at this point in the history
This patch adds a new column 'mark' in the Logical_Switch_Port
table in the NB DB. CMS can set a desired value in this column
and whenever a packet is received from the VIF of the logical port,
the NXM_NX_PKT_MARK field is set with the value specified by CMS.

In the case of Linux, this corresponds to struct sk_buff's "skb_mark"
member and this mark can be seen by the linux networking subsystem.
CMS can inspect this value (as an iptables rule or adding an OF flow
in another ovs bridge) and take appropriate action.

Signed-off-by: Numan Siddique <numans@ovn.org>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
numansiddique authored and ovsrobot committed May 1, 2020
1 parent 3c2908b commit fe4efc4
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 4 deletions.
2 changes: 2 additions & 0 deletions NEWS
Expand Up @@ -13,6 +13,8 @@ OVN v20.03.0 - xx xxx xxxx
- Added support for MLD Snooping and MLD Querier.
- Added support for ECMP routes in OVN router.
- Added IPv6 Prefix Delegation support in OVN.
- Added packet marking support for traffic originating from
the logical port VIFs.

- OVN Interconnection:
* Support for L3 interconnection of multiple OVN deployments with tunnels
Expand Down
5 changes: 5 additions & 0 deletions controller/physical.c
Expand Up @@ -1131,6 +1131,11 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,

load_logical_ingress_metadata(binding, &zone_ids, ofpacts_p);

/* If Mark is set, set the pkt_mark. */
if (binding->n_mark) {
put_load(binding->mark[0], MFF_PKT_MARK, 0, 32, ofpacts_p);
}

/* Resubmit to first logical ingress pipeline table. */
put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p);
ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG,
Expand Down
3 changes: 3 additions & 0 deletions northd/ovn-northd.c
Expand Up @@ -3057,6 +3057,8 @@ ovn_port_update_sbrec(struct northd_context *ctx,
}
sbrec_port_binding_set_external_ids(op->sb, &ids);
smap_destroy(&ids);

sbrec_port_binding_set_mark(op->sb, op->nbsp->mark, op->nbsp->n_mark);
}
int64_t tnl_key = op_get_requested_tnl_key(op);
if (tnl_key && tnl_key != op->sb->tunnel_key) {
Expand Down Expand Up @@ -11841,6 +11843,7 @@ main(int argc, char *argv[])
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_type);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_options);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mac);
add_column_noalert(ovnsb_idl_loop.idl, &sbrec_port_binding_col_mark);
add_column_noalert(ovnsb_idl_loop.idl,
&sbrec_port_binding_col_nat_addresses);
ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_port_binding_col_chassis);
Expand Down
9 changes: 7 additions & 2 deletions ovn-nb.ovsschema
@@ -1,7 +1,7 @@
{
"name": "OVN_Northbound",
"version": "5.22.0",
"cksum": "384164739 25476",
"version": "5.23.0",
"cksum": "3915944754 25731",
"tables": {
"NB_Global": {
"columns": {
Expand Down Expand Up @@ -114,6 +114,11 @@
"refType": "strong"},
"min": 0,
"max": 1}},
"mark": {
"type": {"key": {"type": "integer",
"minInteger": 1,
"maxInteger": 4294967295},
"min": 0, "max": 1}},
"external_ids": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
Expand Down
9 changes: 9 additions & 0 deletions ovn-nb.xml
Expand Up @@ -1254,6 +1254,15 @@
column is ignored.
</column>

<column name="mark">
<p>
The packet received from the VIF of the logical switch port is
marked with the value defined here. CMS can inspect this packet
metadata marker and take some decisions if desired. This value
is not preserved when the packet goes out of the wire.
</p>
</column>

<group title="Naming">
<column name="external_ids" key="neutron:port_name">
<p>
Expand Down
9 changes: 7 additions & 2 deletions ovn-sb.ovsschema
@@ -1,7 +1,7 @@
{
"name": "OVN_Southbound",
"version": "2.7.0",
"cksum": "4286723485 21693",
"version": "2.8.0",
"cksum": "3650018191 21948",
"tables": {
"SB_Global": {
"columns": {
Expand Down Expand Up @@ -189,6 +189,11 @@
"nat_addresses": {"type": {"key": "string",
"min": 0,
"max": "unlimited"}},
"mark": {
"type": {"key": {"type": "integer",
"minInteger": 1,
"maxInteger": 4294967295},
"min": 0, "max": 1}},
"external_ids": {"type": {"key": "string",
"value": "string",
"min": 0,
Expand Down
9 changes: 9 additions & 0 deletions ovn-sb.xml
Expand Up @@ -2582,6 +2582,15 @@ tcp.flags = RST;
</p>
</column>

<column name="mark">
<p>
The packet received from the VIF of the logical switch port is
marked with the value defined here. CMS can inspect this packet
metadata marker and take some decisions if desired. This value
is not preserved when the packet goes out of the wire.
</p>
</column>

<column name="mac">
<p>
The Ethernet address or addresses used as a source address on the
Expand Down
94 changes: 94 additions & 0 deletions tests/ovn.at
Expand Up @@ -19147,3 +19147,97 @@ OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])

OVN_CLEANUP([hv1])
AT_CLEANUP

AT_SETUP([ovn -- Packet marking])
ovn_start

net_add n1
sim_add hv1
as hv1
ovs-vsctl add-br br-phys
ovn_attach n1 br-phys 192.168.0.1
ovs-vsctl -- add-port br-int hv1-vif1 -- \
set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
options:tx_pcap=hv1/vif1-tx.pcap \
options:rxq_pcap=hv1/vif1-rx.pcap \
ofport-request=1

as hv1 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-phys

ovn-nbctl ls-add sw0
ovn-nbctl lsp-add sw0 sw0-port1
ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:03 10.0.0.3"
ovn-nbctl lsp-set-port-security sw0-port1 "50:54:00:00:00:03 10.0.0.3"

ovn-nbctl lsp-add sw0 sw0-port2
ovn-nbctl lsp-set-addresses sw0-port2 "50:54:00:00:00:04 10.0.0.4"

ovn-nbctl lr-add lr0
ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
ovn-nbctl lsp-add sw0 sw0-lr0
ovn-nbctl lsp-set-type sw0-lr0 router
ovn-nbctl lsp-set-addresses sw0-lr0 00:00:00:00:ff:01
ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0

ovn-nbctl ls-add public
ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
ovn-nbctl lsp-add public public-lr0
ovn-nbctl lsp-set-type public-lr0 router
ovn-nbctl lsp-set-addresses public-lr0 router
ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public

# localnet port
ovn-nbctl lsp-add public ln-public
ovn-nbctl lsp-set-type ln-public localnet
ovn-nbctl lsp-set-addresses ln-public unknown
ovn-nbctl lsp-set-options ln-public network_name=public

ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
lr0_dp_uuid=$(ovn-sbctl --bare --columns _uuid list datapath_binding lr0)
ovn-sbctl create mac_binding datapath=$lr0_dp_uuid ip=172.168.0.120 \
logical_port=lr0-public mac="10\:54\:00\:00\:00\:03"

ovn-nbctl --wait=hv sync

AT_CHECK([
test 0 -eq $(as hv1 ovs-ofctl dump-flows br-int table=0 | \
grep in_port=1 | grep NXM_NX_PKT_MARK -c)])

# Set mark on sw0-port1
ovn-nbctl set logical_switch_port sw0-port1 mark=100

OVS_WAIT_UNTIL([
test 1 -eq $(as hv1 ovs-ofctl dump-flows br-int table=0 | \
grep in_port=1 | grep "load:0x64->NXM_NX_PKT_MARK" -c)
])

AT_DATA([flows.txt], [dnl
table=0, priority=0 actions=NORMAL
table=0, priority=100, pkt_mark=0x64 actions=drop
])

AT_CHECK([as hv1 ovs-ofctl --protocols=OpenFlow13 add-flows br-phys flows.txt])

ip_to_hex() {
printf "%02x%02x%02x%02x" "$@"
}

send_ipv4_pkt() {
local hv=$1 inport=$2 eth_src=$3 eth_dst=$4
local ip_src=$5 ip_dst=$6
packet=${eth_dst}${eth_src}08004500001c0000000040110000${ip_src}${ip_dst}0035111100080000
as $hv ovs-appctl netdev-dummy/receive ${inport} ${packet}
}

send_ipv4_pkt hv1 hv1-vif1 505400000003 00000000ff01 \
$(ip_to_hex 10 0 0 3) $(ip_to_hex 172 168 0 120)

OVS_WAIT_UNTIL([
test 1 -eq $(as hv1 ovs-ofctl dump-flows br-phys table=0 | \
grep priority=100 | grep "priority=100,pkt_mark=0x64" | \
grep "n_packets=1" -c)
])

OVN_CLEANUP([hv1])
AT_CLEANUP

0 comments on commit fe4efc4

Please sign in to comment.