eth conflics

I’m experiencing wired behavior from my 9210 modules

basically I have two modules connected into an ethernet switch they have different ip addr but for some reason they can’t live together in the same network

physically connecting the second module make the first disappear from device discovery, module becomes unreachable or very unresponsive.
When second module is disconnected from network first returns to be available again.


IAM - AUTO-CONFIGURED IPv6 address FE80::240:9DFF:FE43:3597 on interface eth0:3 is in initial conflict!
      A random EUI64 Interface ID will be generated.
IAM:AUTO-CONFIGURED IPv6 FE80::6059:BE15:3A71:7243 on eth0:3
IAM:STATIC IPv4 192.168.10.220 on eth0

Hello

00:40:9D:43:57:97 is the default ethernet address given to devices when either they have no other or NVRAM has been squashed and teh contents of NVRAM have defaulted to factory defaults. You should check the ethernet address of both devices to ensure they are not the same. If they are the same you should fix them.

Why do I come to this conclusion? The IPv6 address you show as follows: FE80::240:9DFF:FE43:3597 shows that when the stack went to create the autoIP address it used that default ethernet address I described above,

If both have se same MAC address how can I fix it?

I’m quite scared by this issue with nvram since I do not understand how I caused it and I would make sure it does not repeat when system is deployed on field.

I really need to find out what went wrong before deploying the solution

Have suggestions?

The only time I mess with the NVRAM is within the function I use for IP configuration but personally I do not see anything wrong there.

Still a mystery to me how I could damage the NVRAM and MAC address.

maybe I do not wait enough before exiting the function; in some occasion the function is called by a process that restart the module after the setIpAddress returns;



void setIpAddress (const char *interface, const char *address, const char *gateway, const char *mask, const char *DNS1, const char *DNS2, int use_Dhcp){
    NaIamStaticParams_t staticParams = {0};
    NaIamDhcpParams_t dhcpParams = {0};

    int method;

    /*
   	 * Get current configuration settings.
   	 */
   	if (customizeIamGetStaticConfig(interface, &staticParams) != BP_SUCCESS){
   		printf("[twutils.c] Error Reading Static Configuration From NVRAM" );
        return -1;
   	}

    // DHCP configuration
    if (customizeIamGetDhcpConfig(interface, &dhcpParams) != BP_SUCCESS){
    	printf("[twutils.c] Error Reading DHCP Configuration " );
        return -1;
	}
    else {
        if(use_Dhcp == 1){
            staticParams.isEnabled = FALSE;
            dhcpParams.isEnabled   = TRUE;
        }
        else if(use_Dhcp == 0){
            staticParams.isEnabled = TRUE;
            dhcpParams.isEnabled   = FALSE;
        }
    }

    /*
     * Set IP Address.  The inet_pton function converts a dotted IP address
     * string like "1.2.3.4" into a binary value.
     */
    if (inet_pton(AF_INET, address, &staticParams.ipAddress.addr.ipv4.sin_addr) != 1){
    	printf("[twutils.c] %s Is Not a Valid IP Address.
", address);
        return -1;
    }

    /*
     * Set gateway.
     */
    if (inet_pton(AF_INET, gateway, &staticParams.gateway.addr.ipv4.sin_addr) != 1){
    	printf("[twutils.c] %s Is Not a Valid Gateway Address.
", gateway);
        return -1;
    }

    /*
     * Set subnet mask.
     */
    if (inet_pton(AF_INET, mask, &staticParams.subnetMask) != 1){
    	printf("[twutils.c] %s Is Not a Valid Subnet Mask.
", mask);
        return -1;
    }

    /*
	 * Set Primary DNS.
	 */
	if (inet_pton(AF_INET, DNS1, &staticParams.primaryDns.addr.ipv4.sin_addr) != 1){
	    printf("[twutils.c] %s Is Not a Valid Primary DNS.
", mask);
		return -1;
	}
	/*
	 * Set Secondary DNS.
	 */
	if (inet_pton(AF_INET, DNS2, &staticParams.secondaryDns.addr.ipv4.sin_addr) != 1){
		printf("[twutils.c] %s Is Not a Valid Secondary DNS.
", mask);
		return -1;
	}

    /*
     * Get the method used to set the current IP address.  This
     * information is needed for the call to naIamRelease.
     */
    if (naIamGetCurrentMethod(interface, &method) != BP_SUCCESS)){
        printf("[twutils.c] Error Setting IP Address
" );
        return -1;
    }

    /*
     * Write the new configuration to NVRAM.
     */
	if (customizeIamSetStaticConfig(interface, &staticParams) != BP_SUCCESS){
		printf("[twutils.c] Error Writing the new STATIC IP configuration to NVRAM
" );
	}

	if (customizeIamSetDhcpConfig(interface, &dhcpParams) != BP_SUCCESS)){
		printf("[twutils.c] Error Writing the new DHCP configuration to NVRAM
" );
	}

    //Release current address
    if(naIamRelease(interface, method) != NA_IAM_STATUS_SUCCESS){
        printf("[twutils.c] Error Releasing IP Address
" );
    }

    //Disable current method
    if(naIamDisable(interface, myMethod) != NA_IAM_STATUS_SUCCESS){
         printf("[twutils.c] Error Disabling Current Method
" );
    }
   	
    if(use_Dhcp == 1){
        // Use DHCP
        if(naIamEnable(interface, NA_IAM_METHOD_DHCP) != NA_IAM_STATUS_SUCCESS){
            printf("[twutils.c] Error Enabling IP Acquisition Method
" );
        }
    }
    else if(use_Dhcp == 0){
        // Use static
        if(naIamEnable(interface, NA_IAM_METHOD_STATIC) != NA_IAM_STATUS_SUCCESS){
            printf("[twutils.c]  Error Enabling IP Acquisition Method
" );
        }
    }

    tx_thread_sleep(10);

   
}



Hello
You made the following comment:
" in some occasion the function is called by a process that restart the module after the setIpAddress returns;"

IF you restart the module while NVRAM is still being updated, then you “can” corrupt NVRAM. Remember the way FLASH writes is to erase an entire sector and rewrite it. It does NOT update the bytes you want to update, only. So if you start updating NVRAM and restart the module, you could leave NVRAM in a partially updated state. Thus when you go to read NVRAM after the reboot, the CRC calculation will generate a CRC different from what was recorded. NET+OS sees this as a corruption and will fall back to the default NVRAM values.

Thanks!

Reading in the forum I’ve sse some othere developers used strategies to defend MAC address from default value

I thought to use a .txt file in the flash memory where i specify the 6 digits as written on the label of the modules

example (809E3E)

and test on start if assigned mac address is different from the one specified on the .txt file

post some code would you please confirm i’m using the correct call to set and read the NVRAM ?

int manageMacAddress(){
	int rc = -1;
	int result;
	char label[100] = {};
	char *interface = "eth0";
	BYTE module_mac_addr[6] = {};
	BYTE label_mac_addr[6]  = {};

	FILE * pFile = fopen("FLASH0/MAC.txt", "r" );
	if(pFile <= 0){
		goto _ret;
	}
	result = fread((void*)label, sizeof(char), sizeof(label), pFile);
	label[result] = '\0';
	fclose(pFile);

	if(result > 0){
		int ccode = customizeGetInterfaceMACAddress(interface, module_mac_addr);
		switch(ccode){
			case BP_SUCCESS:
				printf("[macaddress.c] Interface Mac Address %x
", module_mac_addr);
				if(NAConvertMacAddressString(label_mac_addr, label) == BP_SUCCESS){
					if(memcmp(label_mac_addr, module_mac_addr, 6 ) != 0){

						printf("[macaddress.c] Label Mac Address %x
", label_mac_addr);
						printf("[macaddress.c] Interface Mac Address Reset
");
						//Reset Mac Address
						if(customizeSetMACAddress(module_mac_addr) < 0){
							printf("[macaddress.c] Set Mac Address Unable To Read NVRAM
");
							goto _ret;
						}

						rc = 0;
					}
				}
				else{
					printf("[macaddress.c] String Is Not a Valid MAC Address
");
				}
				break;
			case BP_FAILURE:
				printf("[macaddress.c] Get Interface MAC Address BP_FAILURE
");
				break;
			case BP_NO_RESOURCES:
				printf("[macaddress.c] Get Interface MAC Address BP_NO_RESOURCES
");
				break;
			case BP_INVALID_ARGUMENT:
				printf("[macaddress.c] Get Interface MAC Address BP_INVALID_ARGUMENT
");
				break;
		}
	}

	_ret:
    return rc;
}