@@ -987,6 +987,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
987987
988988 /* Translate the message. */
989989 fm -> cookie = ofm -> cookie ;
990+ fm -> cookie_mask = htonll (UINT64_MAX );
990991 command = ntohs (ofm -> command );
991992 fm -> idle_timeout = ntohs (ofm -> idle_timeout );
992993 fm -> hard_timeout = ntohs (ofm -> hard_timeout );
@@ -1001,7 +1002,7 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
10011002 /* Dissect the message. */
10021003 nfm = ofpbuf_pull (& b , sizeof * nfm );
10031004 error = nx_pull_match (& b , ntohs (nfm -> match_len ), ntohs (nfm -> priority ),
1004- & fm -> cr );
1005+ & fm -> cr , & fm -> cookie , & fm -> cookie_mask );
10051006 if (error ) {
10061007 return error ;
10071008 }
@@ -1011,8 +1012,18 @@ ofputil_decode_flow_mod(struct ofputil_flow_mod *fm,
10111012 }
10121013
10131014 /* Translate the message. */
1014- fm -> cookie = nfm -> cookie ;
10151015 command = ntohs (nfm -> command );
1016+ if (command == OFPFC_ADD ) {
1017+ if (fm -> cookie_mask ) {
1018+ /* The "NXM_NX_COOKIE*" matches are not valid for flow
1019+ * additions. Additions must use the "cookie" field of
1020+ * the "nx_flow_mod" structure. */
1021+ return ofp_mkerr (OFPET_BAD_REQUEST , NXBRC_NXM_INVALID );
1022+ } else {
1023+ fm -> cookie = nfm -> cookie ;
1024+ fm -> cookie_mask = htonll (UINT64_MAX );
1025+ }
1026+ }
10161027 fm -> idle_timeout = ntohs (nfm -> idle_timeout );
10171028 fm -> hard_timeout = ntohs (nfm -> hard_timeout );
10181029 fm -> buffer_id = ntohl (nfm -> buffer_id );
@@ -1071,11 +1082,16 @@ ofputil_encode_flow_mod(const struct ofputil_flow_mod *fm,
10711082
10721083 msg = ofpbuf_new (sizeof * nfm + NXM_TYPICAL_LEN + actions_len );
10731084 put_nxmsg (sizeof * nfm , NXT_FLOW_MOD , msg );
1074- match_len = nx_put_match (msg , & fm -> cr );
1075-
10761085 nfm = msg -> data ;
1077- nfm -> cookie = fm -> cookie ;
10781086 nfm -> command = htons (command );
1087+ if (command == OFPFC_ADD ) {
1088+ nfm -> cookie = fm -> cookie ;
1089+ match_len = nx_put_match (msg , & fm -> cr , 0 , 0 );
1090+ } else {
1091+ nfm -> cookie = 0 ;
1092+ match_len = nx_put_match (msg , & fm -> cr ,
1093+ fm -> cookie , fm -> cookie_mask );
1094+ }
10791095 nfm -> idle_timeout = htons (fm -> idle_timeout );
10801096 nfm -> hard_timeout = htons (fm -> hard_timeout );
10811097 nfm -> priority = htons (fm -> cr .priority );
@@ -1104,6 +1120,7 @@ ofputil_decode_ofpst_flow_request(struct ofputil_flow_stats_request *fsr,
11041120 ofputil_cls_rule_from_match (& ofsr -> match , 0 , & fsr -> match );
11051121 fsr -> out_port = ntohs (ofsr -> out_port );
11061122 fsr -> table_id = ofsr -> table_id ;
1123+ fsr -> cookie = fsr -> cookie_mask = htonll (0 );
11071124
11081125 return 0 ;
11091126}
@@ -1120,7 +1137,8 @@ ofputil_decode_nxst_flow_request(struct ofputil_flow_stats_request *fsr,
11201137 ofpbuf_use_const (& b , oh , ntohs (oh -> length ));
11211138
11221139 nfsr = ofpbuf_pull (& b , sizeof * nfsr );
1123- error = nx_pull_match (& b , ntohs (nfsr -> match_len ), 0 , & fsr -> match );
1140+ error = nx_pull_match (& b , ntohs (nfsr -> match_len ), 0 , & fsr -> match ,
1141+ & fsr -> cookie , & fsr -> cookie_mask );
11241142 if (error ) {
11251143 return error ;
11261144 }
@@ -1194,7 +1212,8 @@ ofputil_encode_flow_stats_request(const struct ofputil_flow_stats_request *fsr,
11941212
11951213 subtype = fsr -> aggregate ? NXST_AGGREGATE : NXST_FLOW ;
11961214 ofputil_make_stats_request (sizeof * nfsr , OFPST_VENDOR , subtype , & msg );
1197- match_len = nx_put_match (msg , & fsr -> match );
1215+ match_len = nx_put_match (msg , & fsr -> match ,
1216+ fsr -> cookie , fsr -> cookie_mask );
11981217
11991218 nfsr = msg -> data ;
12001219 nfsr -> out_port = htons (fsr -> out_port );
@@ -1290,7 +1309,8 @@ ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *fs,
12901309 "claims invalid length %zu" , match_len , length );
12911310 return EINVAL ;
12921311 }
1293- if (nx_pull_match (msg , match_len , ntohs (nfs -> priority ), & fs -> rule )) {
1312+ if (nx_pull_match (msg , match_len , ntohs (nfs -> priority ), & fs -> rule ,
1313+ NULL , NULL )) {
12941314 return EINVAL ;
12951315 }
12961316
@@ -1374,7 +1394,7 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
13741394 nfs -> priority = htons (fs -> rule .priority );
13751395 nfs -> idle_timeout = htons (fs -> idle_timeout );
13761396 nfs -> hard_timeout = htons (fs -> hard_timeout );
1377- nfs -> match_len = htons (nx_put_match (msg , & fs -> rule ));
1397+ nfs -> match_len = htons (nx_put_match (msg , & fs -> rule , 0 , 0 ));
13781398 memset (nfs -> pad2 , 0 , sizeof nfs -> pad2 );
13791399 nfs -> cookie = fs -> cookie ;
13801400 nfs -> packet_count = htonll (fs -> packet_count );
@@ -1453,7 +1473,7 @@ ofputil_decode_flow_removed(struct ofputil_flow_removed *fr,
14531473
14541474 nfr = ofpbuf_pull (& b , sizeof * nfr );
14551475 error = nx_pull_match (& b , ntohs (nfr -> match_len ), ntohs (nfr -> priority ),
1456- & fr -> rule );
1476+ & fr -> rule , NULL , NULL );
14571477 if (error ) {
14581478 return error ;
14591479 }
@@ -1503,7 +1523,7 @@ ofputil_encode_flow_removed(const struct ofputil_flow_removed *fr,
15031523 int match_len ;
15041524
15051525 make_nxmsg_xid (sizeof * nfr , NXT_FLOW_REMOVED , htonl (0 ), & msg );
1506- match_len = nx_put_match (msg , & fr -> rule );
1526+ match_len = nx_put_match (msg , & fr -> rule , 0 , 0 );
15071527
15081528 nfr = msg -> data ;
15091529 nfr -> cookie = fr -> cookie ;
0 commit comments