Project: iSulad (Runtime / Container Runtime)
File: native_network_adapter_design.md

| Author | | | | | | Date | 2021-02-19 | | Email | | Native-adaptor mainly includes two parts: config and container network. The config module mainly implements the user's management functions for the network, including the creation, query, and deletion of the network. The container network module mainly performs network creation and deletion operations for a container. ````c struct subnet_scope { char *begin; char *end; }; / Reserved IPv4 address ranges for private networks / const struct subnetscope gprivate_networks[] = { / Class C network 192.168.0.0/16 / { "192.168.0.0/24", "192.168.255.0/24" }, / Class B network 172.16.0.0/12 / { "172.16.0.0/24", "172.31.255.0/24" }, / Class A network 10.0.0.0/8 / { "10.0.0.0/24",

}, }; typedef struct nativenewtorkt { // network conflist struct cninetworklist_conf *conflist; // containers linked to network struct linkedlist containerslist; pthreadrwlockt rwlock; } native_network; typedef struct nativestoret { // string -> ptr(native_newtork) mapt *nameto_network; sizet networklen; char *conf_dir; char bin_paths; sizet binpaths_len; // do not need write lock in nativeinit and nativedestory pthreadrwlockt rwlock; } native_store; struct plugin_op { const char *plugin; cninetconf (op)(const networkcreaterequest *request); }; struct netdriverops { cninetconflist * (*conf)(const networkcreate_request *request); int (check)(const network_create_request request); int (detect)(const char *cnibindir, int bindirlen); int (remove)(cni_net_conf_list list); }; struct net_driver { const char *driver; const struct netdriverops *ops; }; ```` gprivatenetworks records the address of the recognized private network segment, which is used to assign the subnet to create the network nativestoret records the currently saved network information plugin_op records plugin (bridge/portmap/firewall) and its corresponding operation netdriverops and net_driver record the driver (bridge) and its corresponding operation ````c /* Description: Initialize, read the locally stored network conflist, set the directory of the configuration file and bin file; conf_dir: cni configuration file storage directory; bin_paths: cni plugin storage directory list; binpathslen: directory listing length; Return value: return 0 on success, non-zero on failure */ int nativeinit(const char *confdir, const char binpaths, const sizet binpathslen); /* Description: Check if there is an available network; Return value: Returns true if it exists, returns non-false if it does not exist */ bool native_ready(); /* Description: Destroy the network information stored in memory; return value: none */ void native_destory(); /* Description: Add one or more networks to the container; conf: prepared network, container and other information; result: the returned attach result; Return value: return 0 on success, non-zero on failure */ int nativeattachnetworks(const networkapiconf conf, network_api_result_list result); /* Description: remove one or more networks from the container; conf: prepared network, container and other information; result: the returned detach result; Return value: return 0 on success, non-zero on failure */ int nativedetachnetworks(const networkapiconf conf, network_api_result_list result); /* Description: Check whether a network exists; name: the name of the network; Return value: Returns true if it exists, returns non-false if it does not exist */ bool nativenetworkexist(const char *name); /* Description: Create a network; request: request to create a network; response: the return information for creating a network request; Return value: return 0 on success, non-zero on failure */ int nativeconfigcreate(const networkcreaterequest request, network_create_response *response); /* Description: query a network; name: query network name; network_json: the queried network json; Return value: return 0 on success, non-zero on failure */ int nativeconfiginspect(const char name, char *network_json); /* Description: Query all networks; filters: filter conditions; networks: the network information queried; networks_len: the number of queried networks; Return value: return 0 on success, non-zero on failure */ int nativeconfiglist(const struct filtersargs *filters, networknetworkinfo ***networks, sizet *networks_len); /* Description: delete network; name: delete the name of the network; res_name: Returns the deleted network name; Return value: return 0 on success, non-zero on failure */ int nativeconfigremove(const char name, char *res_name); /* Description: Add the container to the container list of a network; network_name: the name of the network; cont_id: the id of the container; Return value: return 0 on success, non-zero on failure */ int nativenetworkaddcontainerlist(const char network_name, const char cont_id); ```` Determine whether the network mode of the container is bridge and the container is not a system container. If it does not meet, exit directly, no need to prepare network for the container. Determine whether the container network has been started, and exit directly if it has been started. Check whether the container network is legal, if it is illegal, exit and report an error. Prepare the network namespace. Prepare attach network, port port mapping data. First attach the loopback device to the container. Attach the specified network plane to the container in turn, and record the result. If it fails, detach the network, delete the network namespace. Update the container's network information, port mapping information, and place it on the disk. Update the hosts and resolve.conf files in the container. Determine whether the network mode of the container is bridge and the container is not a system container. If it does not meet, exit directly, no need to remove network for the container. If the container is in the restart phase, skip the remove network phase. Prepare detached network and port mapping data. First detach the loopback device for the container. The container detaches the network plane. Update the hosts and resolve.conf files in the container. Update the container's network information, port mapping information, and place it on the disk. Delete the container network namespace. Client: Parse the parameters passed in by the user. Verify the incoming parameters, including: Only one network is allowed to be created at a time, that is, at most one name can be specified. If name is specified, check whether the length of name exceeds MAXNETWORKNAME_LEN(128). Send the request to the server Server: Check the received parameters, including If name is specified, check the validity of the name, including whether the length of the name exceeds MAXNETWORKNAME_LEN, and whether the name matches the regular expression ^* $. If the subnet or gateway is specified, check whether the user only specifies the gateway without specifying the subnet, check whether the format of the subnet and gateway is correct, and check whether the subnet and gateway match. If the user specifies a driver, check if the driver is a bridge If the user specifies a name, check whether the name conflicts with the name of the configured native network; if it is not specified, the generated bridge name will be used as the name of the network. The bridge name ensures that it does not conflict with the existing network name, bridge name and network device name on the

If the user specifies a subnet, check whether the subnet network segment is in conflict with the configured network subnet and the host's IP; if it is not specified, find an idle private network segment as the subnet network segment If the user specifies a gateway, set the gateway IP as the IP specified by the user; if not specified, use the first IP in the subnet network segment as the gateway IP Check whether the CNI network plug-in exists on the host Generate network configuration Write the network configuration file Command Line ````sh ~ isula network create --help Usage: isula network create [OPTIONS] [NETWORK] Create a network -d, --driver Driver to manager the network (default "bridge") --gateway IPv4 or IPv6 gateway for the subnet --internal Restrict external access from this network --subnet Subnet in CIDR format ```` grpc interface ````c service NetworkService { rpc Create(NetworkCreateRequest) returns (NetworkCreateResponse); } message NetworkCreateRequest { string name = 1; string driver = 2; string gateway = 3; bool internal = 4; string subnet = 5; } message NetworkCreateResponse { string name = 1; uint32 cc = 2; string errmsg = 3; } ```` rest interface ````c ```` ````sh ~ cat /etc/cni/net.d/isulacni-isula-br0.conflist { "cniVersion": "0.4.0", "name": "isula-br0", "plugins": [ { "type": "bridge", "bridge": "isula-br0", "isGateway": true, "ipMasq": true, "hairpinMode": true, "ipam": { "type": "host-local", "routes": [ { "dst": "0.0.0.0/0" } ], "ranges": [ [ { "subnet": "192.168.0.0/24", "gateway": "192.168.0.1" } ] ] } }, { "type": "portmap", "capabilities": { "portMappings": true } }, { "type": "firewall" } ] } ```` Client: Parse the parameters passed in by the user. Verify the incoming parameters, including Specify at least one name that needs to be queried. If format is specified, check whether the format is legal. Send the request to the server. Server: Verify the received network name. Query the corresponding network in memory. If present, network information json will be returned. If not, return not found. Command Line ````sh isula network inspect [OPTIONS] NETWORK [NETWORK...] -f, --format Format the output using the given go template ```` grpc interface ````c service NetworkService { rpc Inspect(NetworkInspectRequest) returns (NetworkInspectResponse); } message NetworkInspectRequest { string name = 1; } message NetworkInspectResponse { string NetworkJSON = 1; uint32 cc = 2; string errmsg = 3; } ```` rest interface ````c ```` Client: Parse the parameters passed in by the user Send the request to the server Server: Read the request information sent by the client Check whether the condition specified by the filter is legal Filter out the appropriate network according to the filter condition specified by the user and return it to the client Command Line ````sh isula network ls [OPTIONS] -q, --quiet Only display network Names -f, --filter Filter output based on conditions provided ```` grpc interface ````c service NetworkService { rpc List(NetworkListRequest) returns (NetworkListResponse); } message Network { string name = 1; string version = 2; repeated string plugins = 3; } message NetworkListRequest { map<string, string> filters = 1; } message NetworkListResponse { repeated Network networks = 1; uint32 cc = 2; string errmsg = 3; ```` rest interface ````c ```` Client: Parse the parameters passed in by the user. Send a request to the server. Server: Check whether the name is legal. Find the corresponding network. Determine whether any containers use the network. If there is, the network cannot be deleted. Remove the bridge device on the host. Delete the network configuration file. Delete network information in memory. Command Line ````sh isula network rm [OPTIONS] NETWORK [NETWORK...] ```` grpc interface ````c service NetworkService { rpc Remove(NetworkRemoveRequest) returns (NetworkRemoveResponse); } message NetworkRemoveRequest { string name =