gbp: Add support for flow hash profile
[vpp.git] / src / plugins / gbp / gbp_contract.c
index ec54569..ee12a76 100644 (file)
@@ -48,6 +48,7 @@ gbp_rule_alloc (gbp_rule_action_t action,
 
   pool_get_zero (gbp_rule_pool, gu);
 
+  gu->gu_hash_mode = hash_mode;
   gu->gu_nhs = nhs;
   gu->gu_action = action;
 
@@ -158,9 +159,9 @@ format_gbp_rule_action (u8 * s, va_list * args)
 static u8 *
 format_gbp_hash_mode (u8 * s, va_list * args)
 {
-  gbp_hash_mode_t action = va_arg (*args, gbp_hash_mode_t);
+  gbp_hash_mode_t hash_mode = va_arg (*args, gbp_hash_mode_t);
 
-  switch (action)
+  switch (hash_mode)
     {
 #define _(v,a) case GBP_HASH_MODE_##v: return (format (s, "%s", a));
       foreach_gbp_hash_mode
@@ -261,6 +262,23 @@ gbp_contract_mk_adj (gbp_next_hop_t * gnh, fib_protocol_t fproto)
   adj_unlock (old_ai);
 }
 
+static flow_hash_config_t
+gbp_contract_mk_lb_hp (gbp_hash_mode_t gu_hash_mode)
+{
+  switch (gu_hash_mode)
+    {
+    case GBP_HASH_MODE_SRC_IP:
+      return IP_FLOW_HASH_SRC_ADDR;
+    case GBP_HASH_MODE_DST_IP:
+      return IP_FLOW_HASH_DST_ADDR;
+    case GBP_HASH_MODE_SYMMETRIC:
+      return (IP_FLOW_HASH_SRC_ADDR | IP_FLOW_HASH_DST_ADDR |
+             IP_FLOW_HASH_PROTO | IP_FLOW_HASH_SYMMETRIC);
+    }
+
+  return 0;
+}
+
 static void
 gbp_contract_mk_lb (index_t gui, fib_protocol_t fproto)
 {
@@ -307,16 +325,17 @@ gbp_contract_mk_lb (index_t gui, fib_protocol_t fproto)
               dproto, gnh->gnh_ai[fproto]);
     }
 
-    // FIXME get algo and sticky bit from contract LB algo
     if (!dpo_id_is_valid (&gu->gu_dpo[pnode][fproto]))
       {
        dpo_id_t dpo = DPO_INVALID;
 
        dpo_set (&dpo, DPO_LOAD_BALANCE, dproto,
                 load_balance_create (vec_len (paths),
-                                     dproto, IP_FLOW_HASH_DEFAULT));
-       dpo_stack_from_node (policy_nodes[pnode],
-                            &gu->gu_dpo[pnode][fproto], &dpo);
+                                     dproto,
+                                     gbp_contract_mk_lb_hp
+                                     (gu->gu_hash_mode)));
+       dpo_stack_from_node (policy_nodes[pnode], &gu->gu_dpo[pnode][fproto],
+                            &dpo);
        dpo_reset (&dpo);
       }