Support lb on both vip and per-port-vip case
[vpp.git] / src / plugins / lb / cli.c
index 76f05a5..cfe8f38 100644 (file)
@@ -24,12 +24,11 @@ lb_vip_command_fn (vlib_main_t * vm,
   lb_vip_add_args_t args;
   u8 del = 0;
   int ret;
+  u32 port = 0;
   u32 encap = 0;
   u32 dscp = ~0;
   u32 srv_type = LB_SRV_TYPE_CLUSTERIP;
-  u32 port = 0;
   u32 target_port = 0;
-  u32 node_port = 0;
   clib_error_t *error = 0;
 
   args.new_length = 1024;
@@ -50,6 +49,16 @@ lb_vip_command_fn (vlib_main_t * vm,
       ;
     else if (unformat(line_input, "del"))
       del = 1;
+    else if (unformat(line_input, "protocol tcp"))
+      {
+        args.protocol = (u8)IP_PROTOCOL_TCP;
+      }
+    else if (unformat(line_input, "protocol udp"))
+      {
+        args.protocol = (u8)IP_PROTOCOL_UDP;
+      }
+    else if (unformat(line_input, "port %d", &port))
+      ;
     else if (unformat(line_input, "encap gre4"))
       encap = LB_ENCAP_TYPE_GRE4;
     else if (unformat(line_input, "encap gre6"))
@@ -66,12 +75,8 @@ lb_vip_command_fn (vlib_main_t * vm,
       srv_type = LB_SRV_TYPE_CLUSTERIP;
     else if (unformat(line_input, "type nodeport"))
       srv_type = LB_SRV_TYPE_NODEPORT;
-    else if (unformat(line_input, "port %d", &port))
-      ;
     else if (unformat(line_input, "target_port %d", &target_port))
       ;
-    else if (unformat(line_input, "node_port %d", &node_port))
-      ;
     else {
       error = clib_error_return (0, "parse error: '%U'",
                                 format_unformat_error, line_input);
@@ -79,6 +84,17 @@ lb_vip_command_fn (vlib_main_t * vm,
     }
   }
 
+  /* if port == 0, it means all-port VIP */
+  if (port == 0)
+    {
+      args.protocol = ~0;
+      args.port = 0;
+    }
+  else
+    {
+      args.port = (u16)port;
+    }
+
   if ((encap != LB_ENCAP_TYPE_L3DSR) && (dscp != ~0))
     {
       error = clib_error_return(0, "lb_vip_add error: "
@@ -135,9 +151,7 @@ lb_vip_command_fn (vlib_main_t * vm,
                || (encap == LB_ENCAP_TYPE_NAT6))
         {
           args.encap_args.srv_type = (u8) srv_type;
-          args.encap_args.port = (u16) port;
           args.encap_args.target_port = (u16) target_port;
-          args.encap_args.node_port = (u16) node_port;
         }
 
     if ((ret = lb_vip_add(args, &index))) {
@@ -147,7 +161,8 @@ lb_vip_command_fn (vlib_main_t * vm,
       vlib_cli_output(vm, "lb_vip_add ok %d", index);
     }
   } else {
-    if ((ret = lb_vip_find_index(&(args.prefix), args.plen, &index))) {
+    if ((ret = lb_vip_find_index(&(args.prefix), args.plen,
+                                 args.protocol, args.port, &index))) {
       error = clib_error_return (0, "lb_vip_find_index error %d", ret);
       goto done;
     } else if ((ret = lb_vip_del(index))) {
@@ -165,9 +180,11 @@ done:
 VLIB_CLI_COMMAND (lb_vip_command, static) =
 {
   .path = "lb vip",
-  .short_help = "lb vip <prefix> [encap (gre6|gre4|l3dsr|nat4|nat6)] "
+  .short_help = "lb vip <prefix> "
+      "[protocol (tcp|udp) port <n>] "
+      "[encap (gre6|gre4|l3dsr|nat4|nat6)] "
       "[dscp <n>] "
-      "[type (nodeport|clusterip) port <n> target_port <n> node_port <n>] "
+      "[type (nodeport|clusterip) target_port <n>] "
       "[new_len <n>] [del]",
   .function = lb_vip_command_fn,
 };
@@ -181,6 +198,8 @@ lb_as_command_fn (vlib_main_t * vm,
   u8 vip_plen;
   ip46_address_t *as_array = 0;
   u32 vip_index;
+  u32 port = 0;
+  u8 protocol = 0;
   u8 del = 0;
   int ret;
   clib_error_t *error = 0;
@@ -188,30 +207,52 @@ lb_as_command_fn (vlib_main_t * vm,
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
 
-  if (!unformat(line_input, "%U", unformat_ip46_prefix, &vip_prefix, &vip_plen, IP46_TYPE_ANY)) {
+  if (!unformat(line_input, "%U", unformat_ip46_prefix,
+                &vip_prefix, &vip_plen, IP46_TYPE_ANY))
+  {
     error = clib_error_return (0, "invalid as address: '%U'",
                                format_unformat_error, line_input);
     goto done;
   }
 
-  if ((ret = lb_vip_find_index(&vip_prefix, vip_plen, &vip_index))) {
-    error = clib_error_return (0, "lb_vip_find_index error %d", ret);
-    goto done;
-  }
-
   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
   {
-    if (unformat(line_input, "%U", unformat_ip46_address, &as_addr, IP46_TYPE_ANY)) {
+    if (unformat(line_input, "%U", unformat_ip46_address,
+                 &as_addr, IP46_TYPE_ANY))
+    {
       vec_add1(as_array, as_addr);
     } else if (unformat(line_input, "del")) {
       del = 1;
-    } else {
+    }
+    else if (unformat(line_input, "protocol tcp"))
+      {
+          protocol = (u8)IP_PROTOCOL_TCP;
+      }
+    else if (unformat(line_input, "protocol udp"))
+      {
+          protocol = (u8)IP_PROTOCOL_UDP;
+      }
+    else if (unformat(line_input, "port %d", &port))
+      ;
+    else {
       error = clib_error_return (0, "parse error: '%U'",
                                  format_unformat_error, line_input);
       goto done;
     }
   }
 
+  /* If port == 0, it means all-port VIP */
+  if (port == 0)
+    {
+      protocol = ~0;
+    }
+
+  if ((ret = lb_vip_find_index(&vip_prefix, vip_plen, protocol,
+                               (u16)port, &vip_index))){
+    error = clib_error_return (0, "lb_vip_find_index error %d", ret);
+    goto done;
+  }
+
   if (!vec_len(as_array)) {
     error = clib_error_return (0, "No AS address provided");
     goto done;
@@ -221,12 +262,14 @@ lb_as_command_fn (vlib_main_t * vm,
   clib_warning("vip index is %d", vip_index);
 
   if (del) {
-    if ((ret = lb_vip_del_ass(vip_index, as_array, vec_len(as_array)))) {
+    if ((ret = lb_vip_del_ass(vip_index, as_array, vec_len(as_array))))
+    {
       error = clib_error_return (0, "lb_vip_del_ass error %d", ret);
       goto done;
     }
   } else {
-    if ((ret = lb_vip_add_ass(vip_index, as_array, vec_len(as_array)))) {
+    if ((ret = lb_vip_add_ass(vip_index, as_array, vec_len(as_array))))
+    {
       error = clib_error_return (0, "lb_vip_add_ass error %d", ret);
       goto done;
     }
@@ -242,7 +285,8 @@ done:
 VLIB_CLI_COMMAND (lb_as_command, static) =
 {
   .path = "lb as",
-  .short_help = "lb as <vip-prefix> [<address> [<address> [...]]] [del]",
+  .short_help = "lb as <vip-prefix> [protocol (tcp|udp) port <n>]"
+      " [<address> [<address> [...]]] [del]",
   .function = lb_as_command_fn,
 };
 
@@ -335,8 +379,11 @@ lb_show_vips_command_fn (vlib_main_t * vm,
   if (unformat(&line_input, "verbose"))
     verbose = 1;
 
+  /* Hide dummy VIP */
   pool_foreach(vip, lbm->vips, {
+    if (vip != lbm->vips) {
       vlib_cli_output(vm, "%U\n", verbose?format_lb_vip_detailed:format_lb_vip, vip);
+    }
   });
 
   unformat_free (&line_input);