summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorakoshibe <akoshibe@cvs.openbsd.org>2019-11-27 17:37:33 +0000
committerakoshibe <akoshibe@cvs.openbsd.org>2019-11-27 17:37:33 +0000
commit009ad2bc01a6adf57f7d7db01a16a67babc5485a (patch)
tree22086f40f1127536cc6bfd5aba220bccd53247a2 /usr.sbin
parentef9bd43e529c1cca474c19812253e58b17eef098 (diff)
OpenFlow 1.3 defines packet header patterns of interest using TLVs (OXMs)
that represent various header fields. One place where OXMs are used is in the sef_field action, which contains one OXM representing the header field to set, followed by padding to align the action in the OpenFlow message to 64 bits. Currently, we assume that a set_field action can contain multiple OXMs and that they do not need to be padded. This matches the way we handle OpenFlow messages that contain set_field actions so that we follow the specs. OK ori claudio
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/switchd/ofp13.c20
-rw-r--r--usr.sbin/tcpdump/print-ofp.c126
2 files changed, 47 insertions, 99 deletions
diff --git a/usr.sbin/switchd/ofp13.c b/usr.sbin/switchd/ofp13.c
index f02ad1f8840..721302451a7 100644
--- a/usr.sbin/switchd/ofp13.c
+++ b/usr.sbin/switchd/ofp13.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofp13.c,v 1.46 2019/11/21 06:22:57 akoshibe Exp $ */
+/* $OpenBSD: ofp13.c,v 1.47 2019/11/27 17:37:32 akoshibe Exp $ */
/*
* Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
@@ -780,7 +780,7 @@ ofp13_validate_action(struct switchd *sc, struct ofp_header *oh,
print_map(type, ofp_action_map), len, ant->ant_ttl);
break;
case OFP_ACTION_SET_FIELD:
- if (len < sizeof(*asf))
+ if (len < sizeof(*asf) || len != OFP_ALIGN(len))
return (-1);
if ((asf = ibuf_seek(ibuf, *off, sizeof(*asf))) == NULL)
return (-1);
@@ -791,16 +791,14 @@ ofp13_validate_action(struct switchd *sc, struct ofp_header *oh,
print_map(type, ofp_action_map), len);
len -= sizeof(*asf) - sizeof(asf->asf_field);
- while (len > 0) {
- if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm)))
- == NULL)
- return (-1);
- if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
- return (-1);
+ if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
+ return (-1);
+ if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
+ return (-1);
- len -= sizeof(*oxm) + oxm->oxm_length;
- moff += sizeof(*oxm) + oxm->oxm_length;
- }
+ len -= sizeof(*oxm) + oxm->oxm_length;
+ if (len >= OFP_ALIGNMENT)
+ return (-1);
break;
default:
diff --git a/usr.sbin/tcpdump/print-ofp.c b/usr.sbin/tcpdump/print-ofp.c
index 8dd70d4830c..c9037183512 100644
--- a/usr.sbin/tcpdump/print-ofp.c
+++ b/usr.sbin/tcpdump/print-ofp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-ofp.c,v 1.11 2016/11/28 17:47:15 jca Exp $ */
+/* $OpenBSD: print-ofp.c,v 1.12 2019/11/27 17:37:32 akoshibe Exp $ */
/*
* Copyright (c) 2016 Rafael Zalamena <rzalamena@openbsd.org>
@@ -232,10 +232,39 @@ ofp_print_setconfig(const u_char *bp, u_int length)
}
void
+ofp_print_oxm_field(const u_char *bp, u_int length, int omlen, int once)
+{
+ struct ofp_ox_match *oxm;
+
+ do {
+ if (length < sizeof(*oxm)) {
+ printf(" [|OpenFlow]");
+ return;
+ }
+
+ oxm = (struct ofp_ox_match *)bp;
+ bp += sizeof(*oxm);
+ length -= sizeof(*oxm);
+ if (length < oxm->oxm_length) {
+ printf(" [|OpenFlow]");
+ return;
+ }
+
+ ofp_print_oxm(oxm, bp, length);
+ bp += oxm->oxm_length;
+ length -= oxm->oxm_length;
+
+ if (once)
+ return;
+
+ omlen -= min(sizeof(*oxm) + oxm->oxm_length, omlen);
+ } while (omlen > 0);
+}
+
+void
ofp_print_packetin(const u_char *bp, u_int length)
{
struct ofp_packet_in *pin;
- struct ofp_ox_match *oxm;
int omtype, omlen;
int haspacket = 0;
const u_char *pktptr;
@@ -276,27 +305,7 @@ ofp_print_packetin(const u_char *bp, u_int length)
if (omlen == 0)
goto print_packet;
- parse_next_oxm:
- if (length < sizeof(*oxm)) {
- printf(" [|OpenFlow]");
- return;
- }
-
- oxm = (struct ofp_ox_match *)bp;
- bp += sizeof(*oxm);
- length -= sizeof(*oxm);
- if (length < oxm->oxm_length) {
- printf(" [|OpenFlow]");
- return;
- }
-
- ofp_print_oxm(oxm, bp, length);
-
- bp += oxm->oxm_length;
- length -= oxm->oxm_length;
- omlen -= min(sizeof(*oxm) + oxm->oxm_length, omlen);
- if (omlen)
- goto parse_next_oxm;
+ ofp_print_oxm_field(bp, length, omlen, 0);
print_packet:
if (haspacket == 0)
@@ -322,7 +331,6 @@ void
ofp_print_flowremoved(const u_char *bp, u_int length)
{
struct ofp_flow_removed *fr;
- struct ofp_ox_match *oxm;
int omtype, omlen;
if (length < sizeof(*fr)) {
@@ -355,27 +363,7 @@ ofp_print_flowremoved(const u_char *bp, u_int length)
bp += sizeof(*fr);
length -= sizeof(*fr);
- parse_next_oxm:
- if (length < sizeof(*oxm)) {
- printf(" [|OpenFlow]");
- return;
- }
-
- oxm = (struct ofp_ox_match *)bp;
- bp += sizeof(*oxm);
- length -= sizeof(*oxm);
- if (length < oxm->oxm_length) {
- printf(" [|OpenFlow]");
- return;
- }
-
- ofp_print_oxm(oxm, bp, length);
-
- bp += oxm->oxm_length;
- length -= oxm->oxm_length;
- omlen -= min(sizeof(*oxm) + oxm->oxm_length, omlen);
- if (omlen)
- goto parse_next_oxm;
+ ofp_print_oxm_field(bp, length, omlen, 0);
}
void
@@ -453,7 +441,6 @@ void
ofp_print_flowmod(const u_char *bp, u_int length)
{
struct ofp_flow_mod *fm;
- struct ofp_ox_match *oxm;
struct ofp_instruction *i;
int omtype, omlen, ilen;
int instructionslen, padsize;
@@ -498,27 +485,10 @@ ofp_print_flowmod(const u_char *bp, u_int length)
goto parse_next_instruction;
}
- parse_next_oxm:
- if (length < sizeof(*oxm)) {
- printf(" [|OpenFlow]");
- return;
- }
-
- oxm = (struct ofp_ox_match *)bp;
- bp += sizeof(*oxm);
- length -= sizeof(*oxm);
- if (length < oxm->oxm_length) {
- printf(" [|OpenFlow]");
- return;
- }
-
- ofp_print_oxm(oxm, bp, length);
+ ofp_print_oxm_field(bp, length, omlen, 0);
- bp += oxm->oxm_length;
- length -= oxm->oxm_length;
- omlen -= min(sizeof(*oxm) + oxm->oxm_length, omlen);
- if (omlen)
- goto parse_next_oxm;
+ bp += omlen;
+ length -= omlen;
/* Skip padding if any. */
if (padsize) {
@@ -1017,7 +987,6 @@ void
action_print_setfield(const u_char *bp, u_int length)
{
struct ofp_action_set_field *asf;
- struct ofp_ox_match *oxm;
int omlen;
if (length < (sizeof(*asf) - AH_UNPADDED)) {
@@ -1030,27 +999,7 @@ action_print_setfield(const u_char *bp, u_int length)
if (omlen == 0)
return;
- parse_next_oxm:
- if (length < sizeof(*oxm)) {
- printf(" [|OpenFlow]");
- return;
- }
-
- oxm = (struct ofp_ox_match *)bp;
- bp += sizeof(*oxm);
- length -= sizeof(*oxm);
- if (length < oxm->oxm_length) {
- printf(" [|OpenFlow]");
- return;
- }
-
- ofp_print_oxm(oxm, bp, length);
-
- bp += oxm->oxm_length;
- length -= oxm->oxm_length;
- omlen -= min(sizeof(*oxm) + oxm->oxm_length, omlen);
- if (omlen)
- goto parse_next_oxm;
+ ofp_print_oxm_field(bp, length, omlen, 1);
}
void
@@ -1094,6 +1043,7 @@ ofp_print_action(struct ofp_action_header *ah, const u_char *bp, u_int length)
break;
case OFP_ACTION_SET_FIELD:
+ action_print_setfield(bp, length);
break;
case OFP_ACTION_COPY_TTL_OUT: