summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Cantrell <dcantrell@redhat.com>2008-01-31 14:05:22 -1000
committerDavid Cantrell <dcantrell@redhat.com>2008-01-31 14:15:47 -1000
commit158b867f8a1faa48c27eafce0e072a878ccc6f29 (patch)
treed9090a29bc78fa5e7662d2b45007fdc2cdfe58e6
parent93a7149bb4ceaf575ff94216c4ed828a336cf080 (diff)
downloadanaconda-158b867f8a1faa48c27eafce0e072a878ccc6f29.tar.gz
anaconda-158b867f8a1faa48c27eafce0e072a878ccc6f29.tar.xz
anaconda-158b867f8a1faa48c27eafce0e072a878ccc6f29.zip
Remove old IP addresses from interface on reconfig (#218273)
Remove existing IP addresses on the specified interface during a reconfiguration of the interface. The existing code just added more addresses each time. The new address would be there, but the existing one would still be there leading the user to believe the address never changed (you can compare the output of 'ifconfig' and 'ip addr') and see that the ip command shows all addresses. This patch adds a new function called clearInterface() which wraps our pumpDisableInterface() call. It uses libnl to find and delete the existing IP addresses on that interface, then calls the pumpDisableInterface() function. Also fixed a SIGSEGV that can occur in STEP_IP in doLoaderMain() if loaderData->ip is NULL when the check for "query" is done.
-rw-r--r--loader2/loader.c6
-rw-r--r--loader2/net.c71
-rw-r--r--loader2/net.h1
3 files changed, 73 insertions, 5 deletions
diff --git a/loader2/loader.c b/loader2/loader.c
index 2b20ac774..9bc2e99e6 100644
--- a/loader2/loader.c
+++ b/loader2/loader.c
@@ -898,7 +898,7 @@ static char *doLoaderMain(char * location,
STEP_IP, STEP_URL, STEP_DONE } step;
char * url = NULL;
int dir = 1;
- int rc, i;
+ int rc, i, query=0;
char * installNames[10]; /* 10 install methods will be enough for anyone */
int numValidMethods = 0;
@@ -1150,7 +1150,9 @@ static char *doLoaderMain(char * location,
/* fall through to ip config */
case STEP_IP: {
- int query = !strncmp(loaderData->ip, "query", 5);
+ if (loaderData->ip != NULL) {
+ query = !strncmp(loaderData->ip, "query", 5);
+ }
if (!needsNetwork) {
step = STEP_METHOD; /* only hit going back */
diff --git a/loader2/net.c b/loader2/net.c
index eae93c3cd..51f1350c4 100644
--- a/loader2/net.c
+++ b/loader2/net.c
@@ -34,6 +34,10 @@
#include <strings.h>
#include <unistd.h>
#include <kudzu/kudzu.h>
+#include <netinet/in.h>
+#include <netlink/netlink.h>
+#include <netlink/route/addr.h>
+#include <netlink/route/link.h>
#include "../isys/dns.h"
#include "../isys/isys.h"
@@ -1327,6 +1331,63 @@ void netlogger(void *arg, int priority, char *fmt, va_list va) {
return;
}
+/* Clear existing IP addresses from the interface using libnl */
+void clearInterface(char *device) {
+ int ifindex = -1;
+ struct nl_cache *cache = NULL;
+ struct nl_handle *handle = NULL;
+ struct nl_object *obj = NULL;
+ struct rtnl_addr *raddr = NULL;
+
+ if (device == NULL)
+ return;
+
+ if ((handle = nl_handle_alloc()) == NULL) {
+ logMessage(DEBUGLVL, "nl_handle_alloc() failure in clearInterface()");
+ goto clearerr1;
+ }
+
+ if (nl_connect(handle, NETLINK_ROUTE)) {
+ logMessage(DEBUGLVL, "nl_connect() failure in clearInterface()");
+ goto clearerr2;
+ }
+
+ if ((cache = rtnl_link_alloc_cache(handle)) == NULL) {
+ logMessage(DEBUGLVL,
+ "rtnl_link_alloc_cache() failure in clearInterface()");
+ goto clearerr3;
+ }
+
+ ifindex = rtnl_link_name2i(cache, device);
+
+ if ((cache = rtnl_addr_alloc_cache(handle)) == NULL) {
+ logMessage(DEBUGLVL,
+ "rtnl_addr_alloc_cache() failure in clearInterface()");
+ goto clearerr3;
+ }
+
+ obj = nl_cache_get_first(cache);
+ while (obj) {
+ raddr = (struct rtnl_addr *) obj;
+
+ if (rtnl_addr_get_ifindex(raddr) == ifindex) {
+ rtnl_addr_delete(handle, raddr, 0);
+ rtnl_addr_put(raddr);
+ }
+
+ obj = nl_cache_get_next(obj);
+ }
+
+clearerr3:
+ nl_close(handle);
+clearerr2:
+ nl_handle_destroy(handle);
+clearerr1:
+ pumpDisableInterface(device);
+
+ return;
+}
+
char *doDhcp(struct networkDeviceConfig *dev) {
struct pumpNetIntf *i;
char *r = NULL, *class = NULL;
@@ -1336,10 +1397,13 @@ char *doDhcp(struct networkDeviceConfig *dev) {
i = &dev->dev;
+ /* clear existing IP addresses */
+ clearInterface(i->device);
+
if (dev->dhcpTimeout < 0)
- timeout = 45;
+ timeout = 45;
else
- timeout = dev->dhcpTimeout;
+ timeout = dev->dhcpTimeout;
if (dev->vendor_class != NULL)
class = dev->vendor_class;
@@ -1382,6 +1446,7 @@ char *doDhcp(struct networkDeviceConfig *dev) {
int configureNetwork(struct networkDeviceConfig * dev) {
char *rc;
+ clearInterface(dev->dev.device);
setupWireless(dev);
rc = pumpSetupInterface(&dev->dev);
if (rc != NULL) {
@@ -1833,7 +1898,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) {
for (i = 0; devs[i]; i++) {
if (strcmp(loaderData->netDev, devices[i]))
if (!FL_TESTING(flags))
- pumpDisableInterface(devs[i]->device);
+ clearInterface(devs[i]->device);
}
return LOADER_OK;
diff --git a/loader2/net.h b/loader2/net.h
index b625fd1fb..e0084bcba 100644
--- a/loader2/net.h
+++ b/loader2/net.h
@@ -82,6 +82,7 @@ void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
int kickstartNetworkUp(struct loaderData_s * loaderData,
struct networkDeviceConfig *netCfgPtr);
+void clearInterface(char *device);
char *doDhcp(struct networkDeviceConfig *dev);
void netlogger(void *arg, int priority, char *fmt, va_list va);
void splitHostname (char *str, char **host, char **port);