diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c index db2276c540..0e39574edb 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -167,16 +167,24 @@ static const char ebiptables_script_set_ifs[] = #define PHYSDEV_IN "--physdev-in" #define PHYSDEV_OUT "--physdev-is-bridged --physdev-out" +/* + * Previous versions of libvirt only used --physdev-out. + * To be able to upgrade with running VMs we need to be able to + * remove rules generated by those older versions of libvirt. + */ +#define PHYSDEV_OUT_OLD "--physdev-out" static const char *m_state_out_str = "-m state --state NEW,ESTABLISHED"; static const char *m_state_in_str = "-m state --state ESTABLISHED"; static const char *m_physdev_in_str = "-m physdev " PHYSDEV_IN; static const char *m_physdev_out_str = "-m physdev " PHYSDEV_OUT; +static const char *m_physdev_out_old_str = "-m physdev " PHYSDEV_OUT_OLD; #define MATCH_STATE_OUT m_state_out_str #define MATCH_STATE_IN m_state_in_str #define MATCH_PHYSDEV_IN m_physdev_in_str #define MATCH_PHYSDEV_OUT m_physdev_out_str +#define MATCH_PHYSDEV_OUT_OLD m_physdev_out_old_str #define COMMENT_VARNAME "comment" @@ -821,6 +829,8 @@ _iptablesUnlinkRootChain(virBufferPtr buf, : CHAINPREFIX_HOST_OUT; const char *match = (incoming) ? MATCH_PHYSDEV_IN : MATCH_PHYSDEV_OUT; + const char *old_match = (incoming) ? NULL + : MATCH_PHYSDEV_OUT_OLD; PRINT_IPT_ROOT_CHAIN(chain, chainPrefix, ifname); @@ -830,6 +840,18 @@ _iptablesUnlinkRootChain(virBufferPtr buf, basechain, match, ifname, chain); + /* + * Previous versions of libvirt may have created a rule + * with the --physdev-is-bridged missing. Remove this one + * as well. + */ + if (old_match) + virBufferAsprintf(buf, + "$IPT -D %s " + "%s %s -g %s" CMD_SEPARATOR, + basechain, + old_match, ifname, chain); + return 0; }