* New support for matching outer source and destination IP address
of tunneled packets, for tunnel ports configured with the newly
added "remote_ip=flow" and "local_ip=flow" options.
+ * Support for matching on metadata 'pkt_mark' for interacting with
+ other system components. On Linux this corresponds to the skb
+ mark.
- The Interface table in the database has a new "ifindex" column to
report the interface's OS-assigned ifindex.
- New "check-oftest" Makefile target for running OFTest against Open
* - NXM_NX_ND_SLL
* - NXM_NX_ND_TLL
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
+ * - NXM_NX_PKT_MARK
* - NXM_NX_TUN_IPV4_SRC
* - NXM_NX_TUN_IPV4_DST
*
*
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
*
+ * - NXM_NX_PKT_MARK
+ *
* - NXM_OF_VLAN_TCI. Modifying this field's value has side effects on the
* packet's 802.1Q header. Setting a value with CFI=0 removes the 802.1Q
* header (if any), ignoring the other bits. Setting a value with CFI=1
#define NXM_NX_TUN_IPV4_DST NXM_HEADER (0x0001, 32, 4)
#define NXM_NX_TUN_IPV4_DST_W NXM_HEADER_W(0x0001, 32, 4)
+/* Metadata marked onto the packet in a system-dependent manner.
+ *
+ * The packet mark may be used to carry contextual information
+ * to other parts of the system outside of Open vSwitch. As a
+ * result, the semantics depend on system in use.
+ *
+ * Prereqs: None.
+ *
+ * Format: 32-bit integer in network byte order.
+ *
+ * Masking: Fully maskable. */
+#define NXM_NX_PKT_MARK NXM_HEADER (0x0001, 33, 4)
+#define NXM_NX_PKT_MARK_W NXM_HEADER_W(0x0001, 33, 4)
+
/* ## --------------------- ## */
/* ## Requests and replies. ## */
/* ## --------------------- ## */
fmd->tun_dst = flow->tunnel.ip_dst;
fmd->metadata = flow->metadata;
memcpy(fmd->regs, flow->regs, sizeof fmd->regs);
+ fmd->pkt_mark = flow->pkt_mark;
fmd->in_port = flow->in_port.ofp_port;
}
ovs_be32 tun_dst; /* Tunnel outer IPv4 dst addr */
ovs_be64 metadata; /* OpenFlow 1.1+ metadata field. */
uint32_t regs[FLOW_N_REGS]; /* Registers. */
+ uint32_t pkt_mark; /* Packet mark. */
ofp_port_t in_port; /* OpenFlow port or zero. */
};
{
match->flow = *flow;
match->flow.skb_priority = 0;
- match->flow.pkt_mark = 0;
flow_wildcards_init_exact(&match->wc);
}
void
match_set_pkt_mark(struct match *match, uint32_t pkt_mark)
{
- match->wc.masks.pkt_mark = UINT32_MAX;
- match->flow.pkt_mark = pkt_mark;
+ match_set_pkt_mark_masked(match, pkt_mark, UINT32_MAX);
+}
+
+void
+match_set_pkt_mark_masked(struct match *match, uint32_t pkt_mark, uint32_t mask)
+{
+ match->flow.pkt_mark = pkt_mark & mask;
+ match->wc.masks.pkt_mark = mask;
}
void
ds_put_format(s, "priority=%u,", priority);
}
- if (wc->masks.pkt_mark) {
+ switch (wc->masks.pkt_mark) {
+ case 0:
+ break;
+ case UINT32_MAX:
ds_put_format(s, "pkt_mark=%#"PRIx32",", f->pkt_mark);
+ break;
+ default:
+ ds_put_format(s, "pkt_mark=%#"PRIx32"/%#"PRIx32",",
+ f->pkt_mark, wc->masks.pkt_mark);
+ break;
}
if (wc->masks.skb_priority) {
void match_set_tun_flags_masked(struct match *match, uint16_t flags, uint16_t mask);
void match_set_in_port(struct match *, ofp_port_t ofp_port);
void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
+void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask);
void match_set_skb_priority(struct match *, uint32_t skb_priority);
void match_set_dl_type(struct match *, ovs_be16);
void match_set_dl_src(struct match *, const uint8_t[6]);
}, {
MFF_PKT_MARK, "pkt_mark", NULL,
MF_FIELD_SIZES(be32),
- MFM_NONE,
+ MFM_FULLY,
MFS_HEXADECIMAL,
MFP_NONE,
- false,
- 0, NULL,
- 0, NULL,
+ true,
+ NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK",
+ NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK",
},
#define REGISTER(IDX) \
switch (mf->id) {
case MFF_IN_PORT:
case MFF_IN_PORT_OXM:
- case MFF_PKT_MARK:
case MFF_SKB_PRIORITY:
case MFF_ETH_TYPE:
case MFF_DL_VLAN:
ntohl(value->be32), ntohl(mask->be32));
break;
+ case MFF_PKT_MARK:
+ match_set_pkt_mark_masked(match, ntohl(value->be32),
+ ntohl(mask->be32));
+ break;
+
case MFF_ETH_DST:
match_set_dl_dst_masked(match, value->mac, mask->mac);
break;
htonl(flow->regs[i]), htonl(match->wc.masks.regs[i]));
}
+ /* Mark. */
+ nxm_put_32m(b, NXM_NX_PKT_MARK, htonl(flow->pkt_mark),
+ htonl(match->wc.masks.pkt_mark));
+
/* OpenFlow 1.1+ Metadata. */
nxm_put_64m(b, OXM_OF_METADATA, flow->metadata, match->wc.masks.metadata);
}
}
+ if (pin.fmd.pkt_mark != 0) {
+ ds_put_format(string, " pkt_mark=0x%"PRIx32, pin.fmd.pkt_mark);
+ }
+
ds_put_format(string, " (via %s)",
ofputil_packet_in_reason_to_string(pin.reason, reasonbuf,
sizeof reasonbuf));
return OFPUTIL_P_NONE;
}
- /* pkt_mark and skb_priority can't be sent in a flow_mod */
- if (wc->masks.pkt_mark || wc->masks.skb_priority) {
+ /* skb_priority can't be sent in a flow_mod */
+ if (wc->masks.skb_priority) {
return OFPUTIL_P_NONE;
}
+ /* NXM and OXM support pkt_mark */
+ if (wc->masks.pkt_mark) {
+ return OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM
+ | OFPUTIL_P_OF13_OXM;
+ }
+
/* NXM, OXM, and OF1.1 support bitwise matching on ethernet addresses. */
if (!eth_mask_is_exact(wc->masks.dl_src)
&& !eth_addr_is_zero(wc->masks.dl_src)) {
pin->fmd.tun_dst = match->flow.tunnel.ip_dst;
pin->fmd.metadata = match->flow.metadata;
memcpy(pin->fmd.regs, match->flow.regs, sizeof pin->fmd.regs);
+ pin->fmd.pkt_mark = match->flow.pkt_mark;
}
enum ofperr
}
}
+ if (pin->fmd.pkt_mark != 0) {
+ match_set_pkt_mark(match, pin->fmd.pkt_mark);
+ }
+
match_set_in_port(match, pin->fmd.in_port);
}
AT_CAPTURE_FILE([monitor.log])
# Send a packet-out with a load action to set some metadata, and forward to controller
-AT_CHECK([ovs-ofctl packet-out br0 controller 'load(0xfafafafa5a5a5a5a->OXM_OF_METADATA[[0..63]]), controller' '0001020304050010203040501234'])
+AT_CHECK([ovs-ofctl packet-out br0 controller 'load(0xfafafafa5a5a5a5a->OXM_OF_METADATA[[0..63]]), load(0xaa->NXM_NX_PKT_MARK[[]]), controller' '0001020304050010203040501234'])
# Stop the monitor and check its output.
ovs-appctl -t ovs-ofctl ofctl/barrier
ovs-appctl -t ovs-ofctl exit
AT_CHECK([sed 's/ (xid=0x[[0-9a-fA-F]]*)//' monitor.log], [0], [dnl
-NXT_PACKET_IN: total_len=14 in_port=CONTROLLER metadata=0xfafafafa5a5a5a5a (via action) data_len=14 (unbuffered)
+NXT_PACKET_IN: total_len=14 in_port=CONTROLLER metadata=0xfafafafa5a5a5a5a pkt_mark=0xaa (via action) data_len=14 (unbuffered)
metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=00:01:02:03:04:05,dl_type=0x1234
OFPT_BARRIER_REPLY:
])
'metadata=0 NXM,OXM' \
'in_port=1 any' \
'skb_priority=0 none' \
- 'pkt_mark=1 none' \
+ 'pkt_mark=1 NXM,OXM' \
'reg0=0 NXM,OXM' \
'reg1=1 NXM,OXM' \
'reg2=2 NXM,OXM' \
AT_CLEANUP
-AT_SETUP([ovs-ofctl parse-flows (pkt_mark and skb_priority)])
+AT_SETUP([ovs-ofctl parse-flows (skb_priority)])
AT_DATA([flows.txt], [[
-pkt_mark=0x12345678,skb_priority=0x12341234,tcp,tp_src=123,actions=flood
+skb_priority=0x12341234,tcp,tp_src=123,actions=flood
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt
# comment
tcp,tp_src=123,actions=flood
in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
+pkt_mark=0xbb,actions=set_field:0xaa->pkt_mark
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
chosen protocol: NXM+table_id
NXT_FLOW_MOD: ADD table:255 tcp,tp_src=123 actions=FLOOD
NXT_FLOW_MOD: ADD table:255 in_port=LOCAL,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
+NXT_FLOW_MOD: ADD table:255 pkt_mark=0xbb actions=load:0xaa->NXM_NX_PKT_MARK[]
NXT_FLOW_MOD: ADD table:255 udp,dl_vlan_pcp=7 idle:5 actions=strip_vlan,output:0
NXT_FLOW_MOD: ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
NXT_FLOW_MOD: ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
When a packet enters an OpenFlow switch, all of the registers are set
to 0. Only explicit Nicira extension actions change register values.
.
+.IP \fBpkt_mark=\fIvalue\fR[\fB/\fImask\fR]
+Matches packet metadata mark \fIvalue\fR either exactly or with optional
+\fImask\fR. The mark is associated data that may be passed into other
+system components in order to facilitate interaction between subsystems.
+On Linux this corresponds to the skb mark but the exact implementation is
+platform-dependent.
+.
.PP
Defining IPv6 flows (those with \fBdl_type\fR equal to 0x86dd) requires
support for NXM. The following shorthand notations are available for