/* * Mausezahn - A fast versatile traffic generator * Copyright (C) 2008-2010 Herbert Haas * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html * */ #include "mz.h" #include "cli.h" #include "mops.h" int cmd_bpdu_id (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; char str[256]; if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) ) { mz_def16("0x0000", pd->id, str); cli_print(cli, "Specify the BPDU identifier (0..65535)\r"); cli_print(cli, "%s\n", str); cli_print(cli, "\n"); return CLI_OK; } if (mops_pdesc_2byte(&pd->id, argv[0], 0, 0, 65535)) { cli_print(cli, "Specify a value between 0 and 65535\n"); } return CLI_OK; } int cmd_bpdu_version (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) ) { cli_print(cli, "Specify the BPDU version (0..255)\r"); cli_print(cli, "\n"); return CLI_OK; } if (mops_pdesc_1byte(&pd->version, argv[0], 0, 0, 255)) { cli_print(cli, "Specify a value between 0 and 255\n"); } return CLI_OK; } int cmd_bpdu_type (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1) ) { cli_print(cli, "Specify the BPDU type, either via keyword or number (0..255)\n"); cli_print(cli, "Keywords:\n"); cli_print(cli, " conf .... Configuration BPDU\r"); cli_print(cli, " tcn ..... Topology Change BPDU\r"); cli_print(cli, "\n"); return CLI_OK; } if (mz_strcmp(argv[0], "configuration", 1)==0) { pd->bpdu_type = 0x00; } else if (mz_strcmp(argv[0], "tcn", 1)==0) { pd->bpdu_type = 0x80; } else if (mops_pdesc_1byte(&pd->bpdu_type, argv[0], 0, 0, 255)) { cli_print(cli, "Specify a value between 0 and 255\n"); } return CLI_OK; } int cmd_bpdu_flags (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; int i; char str[16]; if ( (strcmp(argv[argc-1],"?")==0) || (argc>8) ) { cli_print(cli, "Specify the BPDU flags by keyword.\r"); cli_print(cli, "Note that not-mentioned flags will be set to zero!\n"); cli_print(cli, "General keywords:\n"); cli_print(cli, " ack .... Topology Change Acknowledgement\r"); cli_print(cli, " tcn .... Topology Change Notification\r"); cli_print(cli, "\r"); cli_print(cli, "RSTP-specific keywords:\n"); cli_print(cli, " agree .... Agreement\r"); cli_print(cli, " prop .... Proposal\r"); cli_print(cli, " fwd .... Forward State\r"); cli_print(cli, " learn .... Learn State\r"); cli_print(cli, "\r"); cli_print(cli, " Port roles:\n"); cli_print(cli, " unknown .... Unknown\r"); cli_print(cli, " alt .... Alternate or Backup\r"); cli_print(cli, " root .... Root\r"); cli_print(cli, " desg .... Designated\r"); cli_print(cli, "\n"); return CLI_OK; } // 7 6 5 4 3 2 1 0 // tcnack agree fwd learn X X proposal TCN // where XX is 00 unknown // 01 alternate or backup // 10 root // 11 designated if (argc) { pd->flags = 0x00; // always reset to zero (= normal Configuration BPDU) for (i=0; iflags |= 0x80; else if (mz_strcmp(argv[i], "tcn", 2)==0) pd->flags |= 0x01; else if (mz_strcmp(argv[i], "agree", 2)==0) pd->flags |= 0x40; else if (mz_strcmp(argv[i], "fwd", 2)==0) pd->flags |= 0x20; else if (mz_strcmp(argv[i], "learn", 2)==0) pd->flags |= 0x10; else if (mz_strcmp(argv[i], "proposal", 2)==0) pd->flags |= 0x02; else if (mz_strcmp(argv[i], "unknown", 2)==0) pd->flags &= 0xf3; else if (mz_strcmp(argv[i], "alt", 2)==0) { pd->flags &= 0xf7; pd->flags |= 0x04; } else if (mz_strcmp(argv[i], "root", 2)==0) { pd->flags &= 0xfb; pd->flags |= 0x08; } else if (mz_strcmp(argv[i], "desg", 2)==0) pd->flags |= 0x0c; } // Feedback char2bits(pd->flags, str); cli_print(cli, "Flags: %s\n", str); } else { cli_print(cli, "No flags configured (use '?')\n"); } return CLI_OK; } int cmd_bpdu_rid (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; char p[64], e[64]; int pri, esi, r; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { cli_print(cli, "Specify the BPDU root identifier, using the following format:\n"); cli_print(cli, " [:ext-sys-id] [interface | MAC-Address]\n"); cli_print(cli, " ....... priority (0-15)\r"); cli_print(cli, " ....... extended system-id (0-4095)\n"); cli_print(cli, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r"); cli_print(cli, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n"); cli_print(cli, "Per default the MAC address of the default interface is used and a priority of zero.\n"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Please specify at least the priority (use ?)\n"); return CLI_OK; } mz_tok(argv[0], ":", 2, p, e); pri = (int) str2int(p); if (e!=NULL) esi = (int) str2int(e); else esi = 0; if (argc==1) // no MAC given { r = mops_create_bpdu_bid (clipkt, pri, esi, NULL, 1); // 1 means RID (0 means BID) } else r = mops_create_bpdu_bid (clipkt, pri, esi, argv[1], 1); // 1 means RID (0 means BID) // Check return value switch (r) { case 1: cli_print(cli, "Priority must be within 0..15\n"); return CLI_OK; break; case 2: cli_print(cli, "Extended System-ID must be within 0..4095\n"); return CLI_OK; break; case 3: cli_print(cli, "Invalid MAC address or interface\n"); return CLI_OK; break; case 4: cli_print(cli, "Invalid format - use ?\n"); return CLI_OK; break; } //--------- // Verify: bs2str(pd->root_id, p, 8); cli_print(cli, "RID is now %s\n", p); // ------- // return CLI_OK; } int cmd_bpdu_pc (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; unsigned long long int i; if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) ) { cli_print(cli, "Specify the BPDU root path cost (0..4294967295)\r"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = str2lint (argv[0]); if (i>0xffffffff) { cli_print(cli, "Range exceeded (0..4294967295)\n"); } else pd->root_pc = (u_int32_t) i; return CLI_OK; } int cmd_bpdu_bid (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; char p[64], e[64]; int pri, esi, r; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { cli_print(cli, "Specify the BPDU bridge identifier, using the following format:\n"); cli_print(cli, " [:ext-sys-id] [interface | MAC-Address]\n"); cli_print(cli, " ....... priority (0-15)\r"); cli_print(cli, " ....... extended system-id (0-4095)\n"); cli_print(cli, "Optionally the MAC address of the root bridge can be given, either directly as arbitrary\r"); cli_print(cli, "address (format: XX:XX:XX:XX:XX:XX) or by referring to an existing interface.\n"); cli_print(cli, "Per default the MAC address of the default interface is used and a priority of zero.\n"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Please specify at least the priority (use ?)\n"); return CLI_OK; } mz_tok(argv[0], ":", 2, p, e); pri = (int) str2int(p); if (e!=NULL) esi = (int) str2int(e); else esi = 0; if (argc==1) // no MAC given { r = mops_create_bpdu_bid (clipkt, pri, esi, NULL, 0); // 0 means BID (1 means RID) } else r = mops_create_bpdu_bid (clipkt, pri, esi, argv[1], 0); // 0 means BID (1 means RID) // Check return value switch (r) { case 1: cli_print(cli, "Priority must be within 0..15\n"); return CLI_OK; break; case 2: cli_print(cli, "Extended System-ID must be within 0..4095\n"); return CLI_OK; break; case 3: cli_print(cli, "Invalid MAC address or interface\n"); return CLI_OK; break; case 4: cli_print(cli, "Invalid format - use ?\n"); return CLI_OK; break; } //--------- // Verify: bs2str(pd->bridge_id, p, 8); cli_print(cli, "BID is now %s\n", p); // ------- // return CLI_OK; } int cmd_bpdu_pid (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; u_int32_t i; if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) ) { cli_print(cli, "Specify the BPDU port identifier (0..65535)\r"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int (argv[0]); if (i>0xffff) { cli_print(cli, "The port identifier must be within 0..65535\n"); return CLI_OK; } pd->port_id = (u_int16_t) i; return CLI_OK; } // // // NOTE: // // All timers are multiples of 1/256 sec. Thus times range from 0 to 255 seconds. // // int cmd_bpdu_age (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; u_int32_t i; char str[256]; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { mz_def16("0", pd->message_age, str); cli_print(cli, "Specify the message age:\n"); cli_print(cli, " - either in seconds (0..256) e. g. '14 sec'\r"); cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n"); cli_print(cli, "%s\n", str); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int (argv[0]); if (argc==1) // absolute { if (i>0xffff) cli_print(cli, "The age must be within 0..65535\n"); else pd->message_age = (u_int16_t) i; } else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds { if (i>256) cli_print(cli, "The age must be within 0..256 seconds\n"); else { if (i==256) i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996 else i = i * 256; pd->message_age = (u_int16_t) i; } } else cli_print(cli, "Invalid argument\n"); return CLI_OK; } int cmd_bpdu_maxage (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; u_int32_t i; char str[256]; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { mz_def16("20 seconds", pd->max_age, str); cli_print(cli, "Specify the maximum message age:\n"); cli_print(cli, " - either in seconds (0..256) e. g. '20 sec'\r"); cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n"); cli_print(cli, "%s\n", str); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int (argv[0]); if (argc==1) // absolute { if (i>0xffff) cli_print(cli, "The max age must be within 0..65535\n"); else pd->max_age = (u_int16_t) i; } else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds { if (i>256) cli_print(cli, "The max age must be within 0..256 seconds\n"); else { if (i==256) i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996 else i = i * 256; pd->max_age = (u_int16_t) i; } } else cli_print(cli, "Invalid argument\n"); return CLI_OK; } int cmd_bpdu_hello (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; u_int32_t i; char str[256]; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { mz_def16("2 seconds", pd->hello_time, str); cli_print(cli, "Specify the hello interval:\n"); cli_print(cli, " - either in seconds (0..256) e. g. '2 sec'\r"); cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n"); cli_print(cli, "%s\n", str); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int (argv[0]); if (argc==1) // absolute { if (i>0xffff) cli_print(cli, "The hello interval must be within 0..65535\n"); else pd->hello_time = (u_int16_t) i; } else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds { if (i>256) cli_print(cli, "The hello interval must be within 0..256 seconds\n"); else { if (i==256) i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996 else i = i * 256; pd->hello_time = (u_int16_t) i; } } else cli_print(cli, "Invalid argument\n"); return CLI_OK; } int cmd_bpdu_fwd (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; u_int32_t i; char str[256]; if ( (strcmp(argv[argc-1],"?")==0) || (argc>2) ) { mz_def16("15 seconds", pd->f_delay, str); cli_print(cli, "Specify the forward delay:\n"); cli_print(cli, " - either in seconds (0..256) e. g. '15 sec'\r"); cli_print(cli, " - or as multiples of 1/256 seconds (0..65535)\n"); cli_print(cli, "%s\n", str); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int (argv[0]); if (argc==1) // absolute { if (i>0xffff) cli_print(cli, "The forward delay must be within 0..65535\n"); else pd->f_delay = (u_int16_t) i; } else if (mz_strcmp(argv[1], "seconds", 1)==0) // in seconds { if (i>256) cli_print(cli, "The forward delay must be within 0..256 seconds\n"); else { if (i==256) i = 0xffff; // since 256*256=65536 which exceeds 0xffff but 65535/256 = 255.996 else i = i * 256; pd->f_delay = (u_int16_t) i; } } else cli_print(cli, "Invalid argument\n"); return CLI_OK; } int cmd_bpdu_mode (struct cli_def *cli, const char *command, char *argv[], int argc) { struct mops_ext_bpdu * pd = clipkt->p_desc; if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) ) { cli_print(cli, "Specify the BPDU mode using the keywords:\n"); cli_print(cli, " stp ...... IEEE 802.1d (traditional CST)\r"); cli_print(cli, " rstp ...... IEEE 802.1w (Rapid STP)\r"); cli_print(cli, " mstp ...... IEEE 802.1s (Multiple STP)\r"); cli_print(cli, " pvst ...... Cisco Per-VLAN STP\r"); cli_print(cli, " rpvst ...... Cisco Per-VLAN RSTP\r"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } if (mz_strcmp(argv[0], "stp", 1)==0) { pd->version=0; pd->rstp=0; pd->pvst=0; pd->mstp=0; } else if (mz_strcmp(argv[0], "rstp", 2)==0) { pd->version=2; pd->rstp=1; pd->mstp=0; } else if (mz_strcmp(argv[0], "mstp", 1)==0) { pd->version=3; pd->mstp=1; } else if (mz_strcmp(argv[0], "pvst", 1)==0) { pd->version=0; pd->pvst=1; pd->rstp=0; pd->mstp=0; } else if (mz_strcmp(argv[0], "rpvst", 2)==0) { pd->version=2; pd->rstp=1; pd->pvst=1; pd->mstp=0; } // TODO: also change version to 2 if RSTP, 0 if legacy return CLI_OK; } int cmd_bpdu_vlan(struct cli_def *cli, const char *command, char *argv[], int argc) { u_int32_t i; if ( (strcmp(argv[argc-1],"?")==0) || (argc>1) ) { cli_print(cli, "Specify the VLAN number for PVST+ messages (0..4095)\n"); cli_print(cli, "\n"); return CLI_OK; } if (argc==0) { cli_print(cli, "Missing argument (use ?)\n"); return CLI_OK; } i = (u_int32_t) str2int(argv[0]); if (i>65535) { cli_print(cli, "VLAN number is definitely too large! (0..65535 at maximum)\n"); return CLI_OK; } if (i>4095) { cli_print(cli, "Warning: Invalid VLAN number (0..4095) - but let's try it...\n"); } mops_create_bpdu_trailer(clipkt, (u_int16_t) i); return CLI_OK; } int cmd_bpdu_end(struct cli_def *cli, const char *command, char *argv[], int argc) { char prompt[16]; sprintf(prompt, "pkt-%i",clipkt->id); cli_set_configmode(cli, MZ_MODE_PACKET, prompt); return CLI_OK; } ove&id=147c1e9b902c25c868024260d24bb0b1dac1433d'>switchdev: bridge: Offload multicast disabledNogah Frankel1-0/+16 Offload multicast disabled flag, for more accurate mc flood behavior: When it is on, the mdb should be ignored. When it is off, unregistered mc packets should be flooded to mc router ports. Signed-off-by: Nogah Frankel <nogahf@mellanox.com> Signed-off-by: Yotam Gigi <yotamg@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Ivan Vecera <ivecera@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: check negative err value to safe one level of indentJiri Pirko1-13/+9 As it is more common, check err for !0. That allows to safe one level of indentation and makes the code easier to read. Also, make 'next' variable global in function as it is used twice. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: add missing curly braces in else branch in tc_ctl_tfilterJiri Pirko1-1/+2 Curly braces need to be there, for stylistic reasons. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: move err set right before goto errout in tc_ctl_tfilterJiri Pirko1-10/+19 This makes the reader to know right away what is the error value. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: push TC filter protocol creation into a separate functionJiri Pirko1-51/+59 Make the long function tc_ctl_tfilter a little bit shorter and easier to read. Also make the creation of filter proto symmetric to destruction. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: move tcf_proto_destroy and tcf_destroy_chain helpers into cls_apiJiri Pirko13-24/+32 Creation is done in this file, move destruction to be at the same place. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10sched: rename tcf_destroy to tcf_destroy_protoJiri Pirko2-6/+6 This function destroys TC filter protocol, not TC filter. So name it accordingly. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10ipv4: fib: Add events for FIB replace and appendIdo Schimmel1-13/+14 The FIB notification chain currently uses the NLM_F_{REPLACE,APPEND} flags to signal routes being replaced or appended. Instead of using netlink flags for in-kernel notifications we can simply introduce two new events in the FIB notification chain. This has the added advantage of making the API cleaner, thereby making it clear that these events should be supported by listeners of the notification chain. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> CC: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10ipv4: fib: Send notification before deleting FIB aliasIdo Schimmel1-7/+7 When a FIB alias is replaced following NLM_F_REPLACE, the ENTRY_ADD notification is sent after the reference on the previous FIB info was dropped. This is problematic as potential listeners might need to access it in their notification blocks. Solve this by sending the notification prior to the deletion of the replaced FIB alias. This is consistent with ENTRY_DEL notifications. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> CC: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10ipv4: fib: Send deletion notification with actual FIB alias typeIdo Schimmel1-2/+2 When a FIB alias is removed, a notification is sent using the type passed from user space - can be RTN_UNSPEC - instead of the actual type of the removed alias. This is problematic for listeners of the FIB notification chain, as several FIB aliases can exist with matching parameters, but the type. Solve this by passing the actual type of the removed FIB alias. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> CC: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-10ipv4: fib: Only flush FIB aliases belonging to currently flushed tableIdo Schimmel1-1/+2 In case the MAIN table is flushed and its trie is shared with the LOCAL table, then we might be flushing FIB aliases belonging to the latter. This can lead to FIB_ENTRY_DEL notifications sent with the wrong table ID. The above doesn't affect current listeners, as the table ID is ignored during entry deletion, but this will change later in the patchset. When flushing a particular table, skip any aliases belonging to a different one. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> CC: Alexander Duyck <alexander.h.duyck@intel.com> CC: Patrick McHardy <kaber@trash.net> Reviewed-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-09openvswitch: Pack struct sw_flow_key.Jarno Rajahalme4-34/+39 struct sw_flow_key has two 16-bit holes. Move the most matched conntrack match fields there. In some typical cases this reduces the size of the key that needs to be hashed into half and into one cache line. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Joe Stringer <joe@ovn.org> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-09openvswitch: Add force commit.Jarno Rajahalme1-2/+24 Stateful network admission policy may allow connections to one direction and reject connections initiated in the other direction. After policy change it is possible that for a new connection an overlapping conntrack entry already exists, where the original direction of the existing connection is opposed to the new connection's initial packet. Most importantly, conntrack state relating to the current packet gets the "reply" designation based on whether the original direction tuple or the reply direction tuple matched. If this "directionality" is wrong w.r.t. to the stateful network admission policy it may happen that packets in neither direction are correctly admitted. This patch adds a new "force commit" option to the OVS conntrack action that checks the original direction of an existing conntrack entry. If that direction is opposed to the current packet, the existing conntrack entry is deleted and a new one is subsequently created in the correct direction. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Pravin B Shelar <pshelar@ovn.org> Acked-by: Joe Stringer <joe@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net> 2017-02-09openvswitch: Add original direction conntrack tuple to sw_flow_key.Jarno Rajahalme