diff options
author | David Cantrell <dcantrell@redhat.com> | 2008-01-31 14:05:22 -1000 |
---|---|---|
committer | David Cantrell <dcantrell@redhat.com> | 2008-01-31 14:15:47 -1000 |
commit | 158b867f8a1faa48c27eafce0e072a878ccc6f29 (patch) | |
tree | d9090a29bc78fa5e7662d2b45007fdc2cdfe58e6 | |
parent | 93a7149bb4ceaf575ff94216c4ed828a336cf080 (diff) | |
download | anaconda-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.c | 6 | ||||
-rw-r--r-- | loader2/net.c | 71 | ||||
-rw-r--r-- | loader2/net.h | 1 |
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); |