VOM: IGMP only supports IPv4 14/16514/2
authorNeale Ranns <nranns@cisco.com>
Mon, 17 Dec 2018 15:29:32 +0000 (07:29 -0800)
committerNeale Ranns <nranns@cisco.com>
Mon, 17 Dec 2018 16:30:50 +0000 (16:30 +0000)
Change-Id: Ie0a8898fa2d8ab71522686fb83fb1de959ee3098
Signed-off-by: Neale Ranns <nranns@cisco.com>
extras/vom/vom/api_types.cpp
extras/vom/vom/api_types.hpp
extras/vom/vom/igmp_binding.cpp
extras/vom/vom/igmp_binding.hpp
extras/vom/vom/igmp_listen.cpp
extras/vom/vom/igmp_listen.hpp
extras/vom/vom/igmp_listen_cmds.cpp

index 9615410..418f3e4 100644 (file)
@@ -28,6 +28,11 @@ to_api(const ip_address_t& a, vapi_type_address& v)
     memcpy(v.un.ip6, a.to_v6().to_bytes().data(), 16);
   }
 }
+void
+to_api(const boost::asio::ip::address& a, vapi_type_ip4_address& v)
+{
+  memcpy(v, a.to_v4().to_bytes().data(), 4);
+}
 
 ip_address_t
 from_api(const vapi_type_address& v)
index 96e2c47..c28ae1e 100644 (file)
@@ -24,8 +24,10 @@ namespace VOM {
 typedef boost::asio::ip::address ip_address_t;
 
 void to_api(const ip_address_t& a, vapi_type_address& v);
+void to_api(const boost::asio::ip::address& a, vapi_type_ip4_address& v);
 
 ip_address_t from_api(const vapi_type_address& v);
+ip_address_t from_api(const vapi_type_ip4_address& v);
 
 vapi_type_mac_address to_api(const mac_address_t& a);
 
index bcdc6cb..73e0bd8 100644 (file)
@@ -22,7 +22,7 @@ namespace VOM {
 /**
  * A DB of all igmp bindings configs
  */
-singular_db<interface::key_t, igmp_binding> igmp_binding::m_db;
+singular_db<igmp_binding::key_t, igmp_binding> igmp_binding::m_db;
 
 igmp_binding::event_handler igmp_binding::m_evh;
 
@@ -41,7 +41,7 @@ igmp_binding::igmp_binding(const igmp_binding& o)
 igmp_binding::~igmp_binding()
 {
   sweep();
-  m_db.release(m_itf->key(), this);
+  m_db.release(key(), this);
 }
 
 bool
@@ -50,6 +50,12 @@ igmp_binding::operator==(const igmp_binding& l) const
   return (*m_itf == *l.m_itf);
 }
 
+const igmp_binding::key_t
+igmp_binding::key() const
+{
+  return (m_itf->key());
+}
+
 void
 igmp_binding::sweep()
 {
@@ -96,7 +102,13 @@ igmp_binding::update(const igmp_binding& desired)
 std::shared_ptr<igmp_binding>
 igmp_binding::find_or_add(const igmp_binding& temp)
 {
-  return (m_db.find_or_add(temp.m_itf->key(), temp));
+  return (m_db.find_or_add(temp.key(), temp));
+}
+
+std::shared_ptr<igmp_binding>
+igmp_binding::find(const key_t& k)
+{
+  return (m_db.find(k));
 }
 
 std::shared_ptr<igmp_binding>
index e2726cd..56af8d1 100644 (file)
@@ -30,6 +30,12 @@ namespace VOM {
 class igmp_binding : public object_base
 {
 public:
+  /**
+   * A binding is tied to a given interface, hence its key is
+   * that of the interface
+   */
+  typedef interface::key_t key_t;
+
   /**
    * Construct a new object matching the desried state
    */
@@ -50,6 +56,11 @@ public:
    */
   bool operator==(const igmp_binding& l) const;
 
+  /**
+   * Get the object's key
+   */
+  const key_t key() const;
+
   /**
    * Return the 'singular' of the IGMP binding that matches this object
    */
@@ -70,6 +81,11 @@ public:
    */
   static void dump(std::ostream& os);
 
+  /**
+   * Find a listen from its key
+   */
+  static std::shared_ptr<igmp_binding> find(const key_t& k);
+
 private:
   /**
    * Class definition for listeners to OM events
@@ -124,7 +140,7 @@ private:
   /**
    * It's the singular_db class that calls replay()
    */
-  friend class singular_db<interface::key_t, igmp_binding>;
+  friend class singular_db<key_t, igmp_binding>;
 
   /**
    * Sweep/reap the object if still stale
@@ -152,7 +168,7 @@ private:
   /**
    * A map of all IGMP bindings keyed against the interface.
    */
-  static singular_db<interface::key_t, igmp_binding> m_db;
+  static singular_db<key_t, igmp_binding> m_db;
 };
 };
 
index 68c5186..8d321ad 100644 (file)
@@ -26,7 +26,7 @@ igmp_listen::event_handler igmp_listen::m_evh;
  * Construct a new object matching the desried state
  */
 igmp_listen::igmp_listen(const igmp_binding& igmp_bind,
-                         const boost::asio::ip::address& gaddr,
+                         const boost::asio::ip::address_v4& gaddr,
                          const igmp_listen::src_addrs_t& saddrs)
   : m_igmp_bind(igmp_bind.singular())
   , m_gaddr(gaddr)
@@ -35,6 +35,15 @@ igmp_listen::igmp_listen(const igmp_binding& igmp_bind,
 {
 }
 
+igmp_listen::igmp_listen(const igmp_binding& igmp_bind,
+                         const boost::asio::ip::address_v4& gaddr)
+  : m_igmp_bind(igmp_bind.singular())
+  , m_gaddr(gaddr)
+  , m_saddrs()
+  , m_listen(true, rc_t::NOOP)
+{
+}
+
 igmp_listen::igmp_listen(const igmp_listen& o)
   : m_igmp_bind(o.m_igmp_bind)
   , m_gaddr(o.m_gaddr)
index cd1da0b..4f07e75 100644 (file)
@@ -31,7 +31,7 @@ namespace VOM {
 class igmp_listen : public object_base
 {
 public:
-  typedef std::set<boost::asio::ip::address> src_addrs_t;
+  typedef std::set<boost::asio::ip::address_v4> src_addrs_t;
 
   /**
    * The key type for igmp_listens
@@ -42,8 +42,10 @@ public:
    * Construct a new object matching the desried state
    */
   igmp_listen(const igmp_binding& igmp_bind,
-              const boost::asio::ip::address& gaddr,
+              const boost::asio::ip::address_v4& gaddr,
               const src_addrs_t& saddrs);
+  igmp_listen(const igmp_binding& igmp_bind,
+              const boost::asio::ip::address_v4& gaddr);
 
   /**
    * Copy Constructor
@@ -162,7 +164,7 @@ private:
   /**
    * The group address for igmp configuration
    */
-  const boost::asio::ip::address m_gaddr;
+  const boost::asio::ip::address_v4 m_gaddr;
 
   /**
    * The set of src addresses to listen for
index cdf0850..683b2b9 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "vom/igmp_listen_cmds.hpp"
+#include "vom/api_types.hpp"
 
 DEFINE_VAPI_MSG_IDS_IGMP_API_JSON;
 
@@ -44,17 +45,24 @@ listen_cmd::issue(connection& con)
 
   auto& payload = req.get_request().get_payload();
   payload.group.sw_if_index = m_itf.value();
-  payload.group.filter = EXCLUDE;
-  to_bytes(m_gaddr.to_v4(), (u8*)&payload.group.gaddr);
-  auto addr = m_saddrs.cbegin();
-  u8 i = 0;
-  while (addr != m_saddrs.cend()) {
-    to_bytes(addr->to_v4(), (u8*)&payload.group.saddrs[i]);
-    addr++;
-    i++;
+  to_api(m_gaddr.to_v4(), payload.group.gaddr);
+
+  if (0 == size) {
+    // no sources => (*,G) join
+    payload.group.filter = EXCLUDE;
+    payload.group.n_srcs = 0;
+  } else {
+    // source => (S,G) join
+    payload.group.filter = INCLUDE;
+    u8 i = 0;
+
+    for (auto addr : m_saddrs) {
+      to_api(addr, payload.group.saddrs[i]);
+      i++;
+    }
+    payload.group.n_srcs = i;
   }
 
-  payload.group.n_srcs = i;
   VAPI_CALL(req.execute());
 
   return (wait());
@@ -99,7 +107,7 @@ unlisten_cmd::issue(connection& con)
   payload.group.sw_if_index = m_itf.value();
   payload.group.n_srcs = 0;
   payload.group.filter = INCLUDE;
-  to_bytes(m_gaddr.to_v4(), (u8*)&payload.group.gaddr);
+  to_api(m_gaddr.to_v4(), payload.group.gaddr);
 
   VAPI_CALL(req.execute());