diff --git a/Dockerfile b/Dockerfile index 59a4a73..488e2ef 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,9 @@ COPY requirements.txt /opt/ RUN pip install -r /opt/requirements.txt RUN mkdir -p /opt/plugin /run/docker/plugins -COPY plugin.sh /opt/plugin/launch.sh COPY net-dhcp/ /opt/plugin/net_dhcp +COPY plugin.sh /opt/plugin/launch.sh + WORKDIR /opt/plugin ENV GUNICORN_OPTS="--log-level=DEBUG" ENTRYPOINT [ "/opt/plugin/launch.sh" ] diff --git a/net-dhcp/network.py b/net-dhcp/network.py index dded796..2386b6c 100644 --- a/net-dhcp/network.py +++ b/net-dhcp/network.py @@ -11,8 +11,9 @@ from flask import request, jsonify from . import NetDhcpError, app -OPTS_KEY = 'com.docker.network.generic' -BRIDGE_OPT = 'devplayer0.net-dhcp.bridge' +OPTS_KEY = 'com.docker.network.generic' +OPT_PREFIX = 'devplayer0.net-dhcp' +OPT_BRIDGE = f'{OPT_PREFIX}.bridge' logger = logging.getLogger('gunicorn.error') @@ -43,7 +44,7 @@ def get_bridges(): set(iface_nets(i)).intersection(reserved_nets), map(lambda i: ndb.interfaces[i.ifname], ndb.interfaces)))) def net_bridge(n): - return ndb.interfaces[client.networks.get(n).attrs['Options'][BRIDGE_OPT]] + return ndb.interfaces[client.networks.get(n).attrs['Options'][OPT_BRIDGE]] @app.route('/NetworkDriver.GetCapabilities', methods=['POST']) def net_get_capabilities(): @@ -55,17 +56,14 @@ def net_get_capabilities(): @app.route('/NetworkDriver.CreateNetwork', methods=['POST']) def create_net(): req = request.get_json(force=True) - if BRIDGE_OPT not in req['Options'][OPTS_KEY]: + if OPT_BRIDGE not in req['Options'][OPTS_KEY]: return jsonify({'Err': 'No bridge provided'}), 400 - desired = req['Options'][OPTS_KEY][BRIDGE_OPT] + desired = req['Options'][OPTS_KEY][OPT_BRIDGE] bridges = get_bridges() if desired not in bridges: return jsonify({'Err': f'Bridge "{desired}" not found (or the specified bridge is already used by Docker)'}), 400 - if request.json['IPv6Data']: - return jsonify({'Err': 'IPv6 is currently unsupported'}), 400 - logger.info('Creating network "%s" (using bridge "%s")', req['NetworkID'], desired) return jsonify({}) @@ -101,21 +99,16 @@ def create_endpoint(): res_iface['MacAddress'] = if_container['address'] def try_addr(type_): + addr = None k = 'AddressIPv6' if type_ == 'v6' else 'Address' if k in req_iface and req_iface[k]: # Just validate the address, Docker will add it to the interface for us - a = ipaddress.ip_address(req_iface[k]) - net = None - for addr in bridge_addrs: - if a == addr.ip: - raise NetDhcpError(400, f'Address {a} is already in use on bridge {bridge["ifname"]}') - if a in addr.network: - net = addr.network - if not net: - raise NetDhcpError(400, f'No suitable network found for {type_} address {a} on bridge {bridge["ifname"]}') - - to_add = f'{a}/{net.prefixlen}' - logger.info('Adding address %s to %s', to_add, if_container['ifname']) + addr = ipaddress.ip_interface(req_iface[k]) + for bridge_addr in bridge_addrs: + if addr.ip == bridge_addr.ip: + raise NetDhcpError(400, f'Address {addr} is already in use on bridge {bridge["ifname"]}') + + logger.info('Adding address %s to %s', addr, if_container['ifname']) elif type_ == 'v4': raise NetDhcpError(400, f'DHCP{type_} is currently unsupported') try_addr('v4')