From 3c8494753dc132311bce8be1d4859cc5209b4e91 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Nov 2008 04:04:51 +0000 Subject: [PATCH] 2008-11-05 Dan Williams * nm-ip4-config.c nm-ip4-config.h - (nm_ip4_config_compare): compare two IP4 configs git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4271 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 6 ++ src/nm-ip4-config.c | 182 ++++++++++++++++++++++++++++++++++++++++++++ src/nm-ip4-config.h | 14 ++++ 3 files changed, 202 insertions(+) diff --git a/ChangeLog b/ChangeLog index e7ddf10c17..76a0ea59e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-05 Dan Williams + + * nm-ip4-config.c + nm-ip4-config.h + - (nm_ip4_config_compare): compare two IP4 configs + 2008-11-05 Dan Williams * src/NetworkManagerPolicy.c diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index bf579657eb..a3e902d1fd 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -453,6 +453,188 @@ nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags) return addr; } +static gboolean +addr_slist_compare (GSList *a, GSList *b) +{ + GSList *iter_a, *iter_b; + gboolean found = FALSE; + + for (iter_a = a; iter_a; iter_a = g_slist_next (iter_a)) { + NMIP4Address *addr_a = (NMIP4Address *) iter_a->data; + + for (iter_b = b, found = FALSE; iter_b; iter_b = g_slist_next (iter_b)) { + NMIP4Address *addr_b = (NMIP4Address *) iter_b->data; + + if (nm_ip4_address_compare (addr_a, addr_b)) { + found = TRUE; + break; + } + } + + if (!found) + return FALSE; + } + return TRUE; +} + +static gboolean +route_slist_compare (GSList *a, GSList *b) +{ + GSList *iter_a, *iter_b; + gboolean found = FALSE; + + for (iter_a = a; iter_a; iter_a = g_slist_next (iter_a)) { + NMIP4Route *route_a = (NMIP4Route *) iter_a->data; + + for (iter_b = b, found = FALSE; iter_b; iter_b = g_slist_next (iter_b)) { + NMIP4Route *route_b = (NMIP4Route *) iter_b->data; + + if (nm_ip4_route_compare (route_a, route_b)) { + found = TRUE; + break; + } + } + + if (!found) + return FALSE; + } + return TRUE; +} + +static gboolean +string_array_compare (GPtrArray *a, GPtrArray *b) +{ + int i, j; + gboolean found = FALSE; + + for (i = 0; i < a->len; i++) { + for (j = 0, found = FALSE; j < b->len; j++) { + const char *item_a = g_ptr_array_index (a, i); + const char *item_b = g_ptr_array_index (b, j); + + if ((!item_a && !item_b) || (item_a && item_b && !strcmp (item_a, item_b))) { + found = TRUE; + break; + } + } + + if (!found) + return FALSE; + } + return TRUE; +} + +static gboolean +addr_array_compare (GArray *a, GArray *b) +{ + int i, j; + gboolean found = FALSE; + + for (i = 0; i < a->len; i++) { + for (j = 0, found = FALSE; j < b->len; j++) { + if (g_array_index (a, guint32, i) == g_array_index (b, guint32, j)) { + found = TRUE; + break; + } + } + + if (!found) + return FALSE; + } + return TRUE; +} + +gboolean +nm_ip4_config_compare (NMIP4Config *a, + NMIP4Config *b, + NMIP4ConfigCompareFlags flags) +{ + NMIP4ConfigPrivate *a_priv = NM_IP4_CONFIG_GET_PRIVATE (a); + NMIP4ConfigPrivate *b_priv = NM_IP4_CONFIG_GET_PRIVATE (b); + + g_return_val_if_fail (NM_IS_IP4_CONFIG (a), FALSE); + g_return_val_if_fail (NM_IS_IP4_CONFIG (b), FALSE); + + if (flags == NM_IP4_COMPARE_FLAG_EXACT) + flags = 0xFFFFFFFF; + + if (flags & NM_IP4_COMPARE_FLAG_ADDRESSES) { + /* Ensure all A exist in B */ + if (!addr_slist_compare (a_priv->addresses, b_priv->addresses)) + return FALSE; + + /* Ensure all B exist in A */ + if (!addr_slist_compare (b_priv->addresses, a_priv->addresses)) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_PTP_ADDRESS) { + if (a_priv->ptp_address != b_priv->ptp_address) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_NAMESERVERS) { + if (a_priv->nameservers->len != b_priv->nameservers->len) /* Shortcut */ + return FALSE; + + /* Ensure all A exist in B */ + if (!addr_array_compare (a_priv->nameservers, b_priv->nameservers)) + return FALSE; + + /* Ensure all B exist in A */ + if (!addr_array_compare (b_priv->nameservers, a_priv->nameservers)) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_ROUTES) { + /* Ensure all A exist in B */ + if (!route_slist_compare (a_priv->routes, b_priv->routes)) + return FALSE; + + /* Ensure all B exist in A */ + if (!route_slist_compare (b_priv->routes, a_priv->routes)) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_DOMAINS) { + if (a_priv->domains->len != b_priv->domains->len) /* Shortcut */ + return FALSE; + + /* Ensure all A exist in B */ + if (!string_array_compare (a_priv->domains, b_priv->domains)) + return FALSE; + + /* Ensure all B exist in A */ + if (!string_array_compare (b_priv->domains, a_priv->domains)) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_SEARCHES) { + if (a_priv->searches->len != b_priv->searches->len) /* Shortcut */ + return FALSE; + + /* Ensure all A exist in B */ + if (!string_array_compare (a_priv->searches, b_priv->searches)) + return FALSE; + + /* Ensure all B exist in A */ + if (!string_array_compare (b_priv->searches, a_priv->searches)) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_MTU) { + if (a_priv->mtu != b_priv->mtu) + return FALSE; + } + + if (flags & NM_IP4_COMPARE_FLAG_MSS) { + if (a_priv->mss != b_priv->mss) + return FALSE; + } + + return TRUE; +} + static void nm_ip4_config_init (NMIP4Config *config) { diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 61ed91d04b..32dfb7de9c 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -101,4 +101,18 @@ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 ms struct rtnl_addr *nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags); +typedef enum { + NM_IP4_COMPARE_FLAG_EXACT = 0x00000000, /* match exactly */ + NM_IP4_COMPARE_FLAG_ADDRESSES = 0x00000001, + NM_IP4_COMPARE_FLAG_PTP_ADDRESS = 0x00000002, + NM_IP4_COMPARE_FLAG_NAMESERVERS = 0x00000004, + NM_IP4_COMPARE_FLAG_ROUTES = 0x00000008, + NM_IP4_COMPARE_FLAG_DOMAINS = 0x00000010, + NM_IP4_COMPARE_FLAG_SEARCHES = 0x00000020, + NM_IP4_COMPARE_FLAG_MTU = 0x00000040, + NM_IP4_COMPARE_FLAG_MSS = 0x00000080 +} NMIP4ConfigCompareFlags; + +gboolean nm_ip4_config_compare (NMIP4Config *a, NMIP4Config *b, NMIP4ConfigCompareFlags flags); + #endif /* NM_IP4_CONFIG_H */