code: func NewNodePlugin(pluginName string, osClient *osclient.Client, kClient *kclient.Client, hostname string, selfIP string, iptablesSyncPeriod time.Duration, mtu uint) (api.OsdnNodePlugin, error) {
  	if !IsOpenShiftNetworkPlugin(pluginName) {
  		return nil, nil
  	}
  
  	log.Infof("Initializing SDN node of type %q with configured hostname %q (IP %q), iptables sync period %q", pluginName, hostname, selfIP, iptablesSyncPeriod.String())
  	if hostname == "" {
  		output, err := kexec.New().Command("uname", "-n").CombinedOutput()
  		if err != nil {
  			return nil, err
  		}
  		hostname = strings.TrimSpace(string(output))
  		log.Infof("Resolved hostname to %q", hostname)
  	}
  	if selfIP == "" {
  		var err error
  		selfIP, err = netutils.GetNodeIP(hostname)
  		if err != nil {
  			log.V(5).Infof("Failed to determine node address from hostname %s; using default interface (%v)", hostname, err)
  			defaultIP, err := kubeutilnet.ChooseHostInterface()
  			if err != nil {
  				return nil, err
  			}
  			selfIP = defaultIP.String()
  			log.Infof("Resolved IP address to %q", selfIP)
  		}
  	}
  
  	plugin := &OsdnNode{
  		multitenant:        IsOpenShiftMultitenantNetworkPlugin(pluginName),
  		registry:           newRegistry(osClient, kClient),
  		localIP:            selfIP,
  		hostName:           hostname,
  		vnids:              newVnidMap(),
  		podNetworkReady:    make(chan struct{}),
  		iptablesSyncPeriod: iptablesSyncPeriod,
  		mtu:                mtu,
  	}
  	return plugin, nil
  }
docs: // Called by higher layers to create the plugin SDN node instance