Allow providers to override glean behaviour
and update glean address on local interface MAC change

Change-Id: I530826d60c7e9db2b0fa2d45754139d82c5ea807
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
diff --git a/src/vnet/adj/adj_glean.c b/src/vnet/adj/adj_glean.c
index 82023f1..82d0a46 100644
--- a/src/vnet/adj/adj_glean.c
+++ b/src/vnet/adj/adj_glean.c
@@ -68,26 +68,55 @@
 	    adj->sub_type.glean.receive_addr = *nh_addr;
 	}
 
+	adj->rewrite_header.sw_if_index = sw_if_index;
 	adj->rewrite_header.data_bytes = 0;
+        adj_lock(adj_get_index(adj));
 
-	vnet_rewrite_for_sw_interface(vnet_get_main(),
-				      adj_fib_proto_2_nd(proto),
-				      sw_if_index,
-				      adj_get_glean_node(proto)->index,
-				      VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST,
-				      &adj->rewrite_header,
-				      sizeof (adj->rewrite_data));
+	vnet_update_adjacency_for_sw_interface(vnet_get_main(),
+                                               sw_if_index,
+                                               adj_get_index(adj));
     }
     else
     {
 	adj = adj_get(adj_gleans[proto][sw_if_index]);
+        adj_lock(adj_get_index(adj));
     }
 
-    adj_lock(adj_get_index(adj));
-
     return (adj_get_index(adj));
 }
 
+/**
+ * adj_glean_update_rewrite
+ */
+void
+adj_glean_update_rewrite (adj_index_t adj_index)
+{
+    ip_adjacency_t *adj;
+
+    ASSERT(ADJ_INDEX_INVALID != adj_index);
+
+    adj = adj_get(adj_index);
+
+    vnet_rewrite_for_sw_interface(vnet_get_main(),
+                                  adj_fib_proto_2_nd(adj->ia_nh_proto),
+                                  adj->rewrite_header.sw_if_index,
+                                  adj_get_glean_node(adj->ia_nh_proto)->index,
+                                  VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST,
+                                  &adj->rewrite_header,
+                                  sizeof (adj->rewrite_data));
+}
+
+adj_index_t
+adj_glean_get (fib_protocol_t proto,
+               u32 sw_if_index)
+{
+    if (sw_if_index < vec_len(adj_gleans[proto]))
+    {
+        return (adj_gleans[proto][sw_if_index]);
+    }
+    return (ADJ_INDEX_INVALID);
+}
+
 void
 adj_glean_remove (fib_protocol_t proto,
 		  u32 sw_if_index)
@@ -227,12 +256,17 @@
     vnet_main_t * vnm = vnet_get_main();
     ip_adjacency_t * adj = adj_get(index);
 
-    return (format(s, "%U-glean: %U",
-		   format_fib_protocol, adj->ia_nh_proto,
-                   format_vnet_sw_interface_name,
-                   vnm,
-                   vnet_get_sw_interface(vnm,
-                                         adj->rewrite_header.sw_if_index)));
+    s = format(s, "%U-glean: %U",
+               format_fib_protocol, adj->ia_nh_proto,
+               format_vnet_sw_interface_name,
+               vnm,
+               vnet_get_sw_interface(vnm,
+                                     adj->rewrite_header.sw_if_index));
+    s = format (s, " %U",
+		format_vnet_rewrite,
+		&adj->rewrite_header, sizeof (adj->rewrite_data), 0);
+
+    return (s);
 }