Multi Path Routing - 3/4 th Done
diff --git a/nlsr_adl.c b/nlsr_adl.c
index 25af57d..ec78eb8 100644
--- a/nlsr_adl.c
+++ b/nlsr_adl.c
@@ -763,4 +763,29 @@
 	return connecting_face;
 }
 
+int 
+is_neighbor(char *nbr)
+{
+	int ret=0;
+
+	int res;
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = ⅇ
+
+	hashtb_start(nlsr->adl, e);
+	res = hashtb_seek(e, nbr, strlen(nbr)+1, 0);
+
+	if( res == HT_OLD_ENTRY )
+	{
+		ret=1;	
+	}
+	else if(res == HT_NEW_ENTRY)
+	{
+		hashtb_delete(e);
+	}
+
+	hashtb_end(e);
+
+	return ret;
+}
 
diff --git a/nlsr_adl.h b/nlsr_adl.h
index ac6c066..a1f48b2 100644
--- a/nlsr_adl.h
+++ b/nlsr_adl.h
@@ -46,4 +46,5 @@
 void update_adjacent_lsdb_version_to_adl(struct name_prefix *nbr, char *version);
 void adjust_adjacent_last_lsdb_requested_to_adl(char *nbr, long int sec);
 int get_next_hop_face_from_adl(char *nbr);
+int is_neighbor(char *nbr);
 #endif
diff --git a/nlsr_lsdb.c b/nlsr_lsdb.c
index 0a88b5e..16a7f30 100644
--- a/nlsr_lsdb.c
+++ b/nlsr_lsdb.c
@@ -203,13 +203,14 @@
 			set_new_lsdb_version();	
 			printf("New Version Number of LSDB: %s \n",nlsr->lsdb->lsdb_version);	
 
-			int next_hop=get_next_hop(new_name_lsa->header->orig_router->name);
+			//struct hashtb *face_list;
+			int num_next_hop=get_number_of_next_hop(new_name_lsa->header->orig_router->name);
 
 			//printf("Next hop: %d \n",next_hop);
 
-			if ( next_hop == NO_NEXT_HOP )
+			if ( num_next_hop < 0 )
 			{
-				int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,NO_FACE);
+				int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,NO_NEXT_HOP,NULL,NULL);
 				if ( check == HT_NEW_ENTRY )
 				{
 					printf("Added in npt \n");
@@ -217,16 +218,26 @@
 			}
 			else 
 			{
-				int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,next_hop);
+				int *faces=malloc(num_next_hop*sizeof(int));
+				int *route_costs=malloc(num_next_hop*sizeof(int));			
+				int next_hop=get_next_hop(new_name_lsa->header->orig_router->name,faces,route_costs);
+				printf("Printing from install_name_lsa \n");
+				int j;
+				for(j=0;j<num_next_hop;j++)
+					printf("Face: %d Route Cost: %d \n",faces[j],route_costs[j]);
+				int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,next_hop,faces,route_costs);
 				if ( check == HT_NEW_ENTRY )
 				{
 					printf("Added in npt \n");
 				}
+				free(faces);
+				free(route_costs);
 
 			}
+			
 
 		
-		free(time_stamp);
+			free(time_stamp);
 
 		}
 		else if(res == HT_OLD_ENTRY)
@@ -295,10 +306,12 @@
 
 					if( is_npt_update == 1 )
 					{
-						int next_hop=get_next_hop(new_name_lsa->header->orig_router->name);
-						if ( next_hop == NO_NEXT_HOP )
+						//struct hashtb *face_list;
+						int num_next_hop=get_number_of_next_hop(new_name_lsa->header->orig_router->name);
+						if ( num_next_hop < 0 )
 						{
-							int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,NO_FACE);
+							
+							int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,NO_NEXT_HOP,NULL,NULL);
 							if ( check == HT_NEW_ENTRY )
 							{
 								printf("Added in npt \n");
@@ -306,12 +319,24 @@
 						}
 						else 
 						{
-							int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,next_hop);
+							int *faces=malloc(num_next_hop*sizeof(int));
+							int *route_costs=malloc(num_next_hop*sizeof(int));			
+							int next_hop=get_next_hop(new_name_lsa->header->orig_router->name,faces,route_costs);
+							printf("Printing from install_name_lsa \n");
+							int j;
+							for(j=0;j<num_next_hop;j++)
+								printf("Face: %d Route Cost: %d \n",faces[j],route_costs[j]);
+							
+							int check=add_npt_entry(new_name_lsa->header->orig_router->name,new_name_lsa->name_prefix->name,next_hop,faces,route_costs);
 							if ( check == HT_NEW_ENTRY )
 							{
 								printf("Added in npt \n");
 							}
+							free(faces);
+							free(route_costs);
+							
 						}
+						
 					}
 				}
 			}
@@ -379,7 +404,7 @@
 	print_name_lsa(name_lsa);
 	install_name_lsa(name_lsa);
 	print_name_lsdb();
-
+	print_npt();
 	
 	free(name_lsa->header->orig_router->name);
 	free(name_lsa->header->orig_router);
@@ -587,8 +612,8 @@
 			set_new_lsdb_version();	
 			printf("New Version Number of LSDB: %s \n",nlsr->lsdb->lsdb_version);
 
+			
 			add_next_hop_router(new_adj_lsa->header->orig_router->name);
-
 			add_next_hop_from_lsa_adj_body(new_adj_lsa->body,new_adj_lsa->no_link);
 		}
 		else if(res == HT_OLD_ENTRY)
diff --git a/nlsr_npt.c b/nlsr_npt.c
index a4f3e33..5f6ee26 100644
--- a/nlsr_npt.c
+++ b/nlsr_npt.c
@@ -26,7 +26,7 @@
 #include "nlsr_route.h"
 
 int
-add_npt_entry(char *orig_router, char *name_prefix, int face)
+add_npt_entry(char *orig_router, char *name_prefix, int num_face, int *faces, int *route_costs)
 {
 	if ( strcmp(orig_router,nlsr->router_name)== 0)
 	{
@@ -35,7 +35,7 @@
 	
 	struct npt_entry *ne=(struct npt_entry*)malloc(sizeof(struct npt_entry ));
 	
-	int res,res_nle;
+	int res,res_nle,res_fle;
 	struct hashtb_enumerator ee;
     	struct hashtb_enumerator *e = &ee; 	
     
@@ -52,7 +52,7 @@
 		memcpy(ne->orig_router,orig_router,strlen(orig_router));
 
 	
-		struct name_list_entry *nle=(struct name_list_entry *)malloc(sizeof(struct name_list_entry));
+		
 
 		struct hashtb_param param_nle = {0};
 		ne->name_list= hashtb_create(sizeof(struct name_list_entry ), &param_nle);
@@ -65,6 +65,7 @@
 
 		if(res_nle == HT_NEW_ENTRY )
 		{
+			struct name_list_entry *nle=(struct name_list_entry *)malloc(sizeof(struct name_list_entry));
 			nle=enle->data;
 			nle->name=(char *)malloc(strlen(name_prefix)+1);
 			memset(nle->name,0,strlen(name_prefix)+1);
@@ -75,13 +76,43 @@
 		}
 		hashtb_end(enle);
 
-		ne->next_hop_face=face;
+		struct hashtb_param param_fle = {0};
+		ne->face_list=hashtb_create(sizeof(struct face_list_entry), &param_fle);
 
+		if ( num_face > 0 )
+		{
+			struct hashtb_enumerator eef;
+    			struct hashtb_enumerator *ef = &eef;
+    	
+    			hashtb_start(ne->face_list, ef);
+			int i;						
+
+			for ( i=0; i< num_face ; i ++)
+			{
+				int face=faces[i];
+				res_fle = hashtb_seek(ef, &face, sizeof(face), 0);
+				
+				if ( res_fle == HT_NEW_ENTRY )
+				{
+					struct face_list_entry *fle=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
+					fle=ef->data;
+					fle->next_hop_face=face;
+					fle->route_cost=route_costs[i];
+				}
+		
+			}
+			hashtb_end(ef);
+		}
+		
+
+		//ne->next_hop_face=face;
+
+		/*
 		if ( face != NO_FACE )
 		{
 			add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)name_prefix, OP_REG, face);
 		}
-	
+		*/
 	}
 	else if (res == HT_OLD_ENTRY)
 	{
@@ -90,11 +121,6 @@
 
 		one=e->data;
 		
-		struct name_list_entry *nle=(struct name_list_entry *)malloc(sizeof(struct name_list_entry));
-
-		struct hashtb_param param_nle = {0};
-		ne->name_list= hashtb_create(sizeof(struct name_list_entry ), &param_nle);
-
 		struct hashtb_enumerator eenle;
     		struct hashtb_enumerator *enle = &eenle;
 
@@ -103,22 +129,48 @@
 
 		if(res_nle == HT_NEW_ENTRY )
 		{
+			struct name_list_entry *nle=(struct name_list_entry *)malloc(sizeof(struct name_list_entry));
 			nle=enle->data;
 			nle->name=(char *)malloc(strlen(name_prefix)+1);
 			memset(nle->name,0,strlen(name_prefix)+1);
 			memcpy(nle->name,name_prefix,strlen(name_prefix));
-			
+			/*
 			if ( face != NO_FACE )
 			{
 				add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)name_prefix, OP_REG, face);
 			}
+			*/
 		}
 		else if(res_nle == HT_OLD_ENTRY )
 		{
-			free(nle);
+			
 		}
 		hashtb_end(enle);
 
+		if ( num_face > 0 )
+		{
+			struct hashtb_enumerator eef;
+    			struct hashtb_enumerator *ef = &eef;
+    	
+    			hashtb_start(one->face_list, ef);
+			int i;						
+
+			for ( i=0; i< num_face ; i ++)
+			{
+				int face=faces[i];
+				res_fle = hashtb_seek(ef, &face, sizeof(face), 0);
+				
+				if ( res_fle == HT_NEW_ENTRY )
+				{
+					struct face_list_entry *fle=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
+					fle=ef->data;
+					fle->next_hop_face=face;
+					fle->route_cost=route_costs[i];
+				}
+		
+			}
+			hashtb_end(ef);
+		}
 	
 
 	}
@@ -165,10 +217,12 @@
 		}
 		else if(res_nle == HT_OLD_ENTRY )
 		{
+			/*
 			if (ne->next_hop_face != NO_FACE )
 			{
 				add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)name_prefix, OP_UNREG, ne->next_hop_face);
 			}
+			*/
 			hashtb_delete(enle);
 		}
 
@@ -206,9 +260,9 @@
 		printf("----------NPT ENTRY %d------------------\n",i+1);
 		ne=e->data;
 		printf(" Origination Router: %s \n",ne->orig_router);
-		ne->next_hop_face == NO_FACE ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", ne->next_hop_face);
+		//ne->next_hop_face == NO_FACE ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", ne->next_hop_face);
 		
-		int j, nl_element;
+		int j, nl_element,face_list_element;
 		struct name_list_entry *nle;		
 		struct hashtb_enumerator eenle;
     		struct hashtb_enumerator *enle = &eenle;
@@ -223,6 +277,29 @@
 			hashtb_next(enle);
 		}
 		hashtb_end(enle);
+
+		struct face_list_entry *fle;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(ne->face_list, ef);
+		face_list_element=hashtb_n(ne->face_list);
+		if ( face_list_element <= 0 )
+		{
+			printf(" 	Face: No Face \n");
+		}
+		else
+		{
+			for(j=0;j<face_list_element;j++)
+			{
+				fle=ef->data;
+				printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
+				hashtb_next(ef);	
+			}
+		}
+		hashtb_end(ef);
+		
 			
 		hashtb_next(e);		
 	}
@@ -233,9 +310,9 @@
 }
 
 void
-delete_orig_router_from_npt(char *orig_router,int next_hop_face)
+delete_orig_router_from_npt(char *orig_router)
 {
-	int res;
+	int res,num_face,num_prefix;
 	struct npt_entry *ne;
 
 	struct hashtb_enumerator ee;
@@ -247,9 +324,12 @@
 	if ( res == HT_OLD_ENTRY )
 	{
 		ne=e->data;
-		if ( next_hop_face == ne->next_hop_face )
+		num_prefix=hashtb_n(ne->name_list);
+		if ( num_prefix > 0 )
 		{
-			if ( next_hop_face != NO_NEXT_HOP )
+			num_face=hashtb_n(ne->face_list);
+			
+			if ( num_face > 0  )
 			{
 				int j, nl_element;
 				struct name_list_entry *nle;		
@@ -262,7 +342,26 @@
 				for (j=0;j<nl_element;j++)
 				{
 					nle=enle->data;
-					add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)nle->name, OP_UNREG , next_hop_face);
+		
+					int k,face_list_element;
+					struct face_list_entry *fle;
+
+					struct hashtb_enumerator eef;
+    					struct hashtb_enumerator *ef = &eef;
+    	
+    					hashtb_start(ne->face_list, ef);
+					face_list_element=hashtb_n(ne->face_list);
+					for(k=0;k<face_list_element;k++)
+					{
+						fle=ef->data;
+						//printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
+						//add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)nle->name, OP_UNREG , next_hop_face);
+						hashtb_next(ef);	
+					}
+					hashtb_end(ef);
+
+						//add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)nle->name, OP_UNREG , next_hop_face);
+					
 					hashtb_next(enle);
 				}
 				hashtb_end(enle);				
@@ -271,6 +370,7 @@
 
 		}
 		hashtb_destroy(&ne->name_list);
+		hashtb_destroy(&ne->face_list);
 		hashtb_delete(e);		
 	}
 	else if ( res == HT_NEW_ENTRY )
@@ -280,6 +380,7 @@
 	hashtb_end(e);	
 }
 
+/*
 
 void 
 update_npt_with_new_route(char * orig_router,int next_hop_face)
@@ -332,6 +433,283 @@
 	hashtb_end(e);
 }
 
+*/
+
+
+void
+add_face_to_npt_by_face_id(char *dest_router, int face_id, int route_cost)
+{
+	printf("add_face_to_npt_by_face_id called\n");
+
+	printf("Dest Router: %s Face: %d Route_cost: %d \n",dest_router, face_id, route_cost);
+	int res,res1;
+	struct npt_entry *ne;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->npt, e);
+	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);
+
+	if ( res == HT_OLD_ENTRY )
+	{
+		printf("Dest Router Found \n");
+		ne=e->data;
+		
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(ne->face_list, ef);
+		res1=hashtb_seek(ef, &face_id, sizeof(face_id), 0);
+
+		if ( res1 == HT_OLD_ENTRY )
+		{
+			printf("Face Found \n");
+			struct face_list_entry *fle;//=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
+			fle=ef->data;
+			fle->next_hop_face=face_id;
+			fle->route_cost=route_cost;
+		}
+		else if ( res1 == HT_NEW_ENTRY )
+		{
+			printf("Face Not Found \n");
+			struct face_list_entry *fle=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
+			fle=ef->data;
+			fle->next_hop_face=face_id;
+			fle->route_cost=route_cost;
+			//hashtb_delete(ef);
+		}
+		hashtb_end(ef);
+	}
+	else if (res == HT_NEW_ENTRY)
+	{
+		hashtb_delete(e);
+	}
+	
+	hashtb_end(e);
+}
+
+
+void
+add_new_fib_entries_to_npt()
+{
+	printf("add_new_fib_entries_to_npt called\n");
+	int i,j, rt_element,face_list_element;
+	
+	struct routing_table_entry *rte;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->routing_table, e);
+	rt_element=hashtb_n(nlsr->routing_table);
+
+	for(i=0;i<rt_element;i++)
+	{
+		//printf("----------Routing Table Entry %d------------------\n",i+1);
+		rte=e->data;
+		//printf(" Destination Router: %s \n",rte->dest_router);
+		//rte->next_hop_face == NO_NEXT_HOP ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", rte->next_hop_face);
+
+		struct face_list_entry *fle;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(rte->face_list, ef);
+		face_list_element=hashtb_n(rte->face_list);
+		if ( face_list_element <= 0 )
+		{
+			printf(" 	Face: No Face \n");
+		}
+		else
+		{
+			for(j=0;j<face_list_element;j++)
+			{
+				fle=ef->data;
+				//printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
+				add_face_to_npt_by_face_id(rte->dest_router,fle->next_hop_face,fle->route_cost);
+				hashtb_next(ef);	
+			}
+		}
+		hashtb_end(ef);
+
+		hashtb_next(e);		
+	}
+
+	hashtb_end(e);
+
+}
+
+
+void
+delete_face_from_npt_by_face_id(char *dest_router, int face_id)
+{
+	printf("delete_face_from_npt_by_face_id called\n");
+
+	int res,res1;
+	struct npt_entry *ne;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->npt, e);
+	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);
+
+	if ( res == HT_OLD_ENTRY )
+	{
+		ne=e->data;
+		
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(ne->face_list, ef);
+		res1=hashtb_seek(ef, &face_id, sizeof(face_id), 0);
+
+		if ( res1 == HT_OLD_ENTRY )
+		{
+			hashtb_delete(ef);
+		}
+		else if ( res1 == HT_NEW_ENTRY )
+		{
+			hashtb_delete(ef);
+		}
+		hashtb_end(ef);
+	}
+	else if (res == HT_NEW_ENTRY)
+	{
+		hashtb_delete(e);
+	}
+	
+	hashtb_end(e);
+}
+
+int
+delete_old_face_from_npt(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
+{
+	if(flags == CCN_SCHEDULE_CANCEL)
+	{
+ 	 	return -1;
+	}
+	
+	nlsr_lock();
+
+	printf("delete_old_face_from_npt called\n");
+	if ( ev->evdata != NULL )
+	{	
+		printf("Event Data: %s \n",(char *)ev->evdata);	
+		char *sep="|";
+		char *rem;
+		char *orig_router;
+		char *faceid;
+		int face_id;
+
+		char *face_data=(char *)malloc(strlen((char *)ev->evdata)+1);
+		memset(face_data,0,strlen((char *)ev->evdata)+1);
+		memcpy(face_data+strlen(face_data),(char *)ev->evdata,strlen((char *)ev->evdata));
+
+		orig_router=strtok_r(face_data,sep,&rem);
+		faceid=strtok_r(NULL,sep,&rem);
+		face_id=atoi(faceid);
+		printf("Orig Router: %s Face: %d \n",orig_router,face_id);
+
+		delete_face_from_npt_by_face_id(orig_router,face_id);		
+	}
+
+	nlsr_unlock();
+	
+	return 0;
+}
+
+void 
+clean_old_fib_entries_from_npt()
+{
+	
+	printf("clean_old_fib_entries_from_npt called\n\n");
+	int i, npt_element;
+	
+	struct npt_entry *ne;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->npt, e);
+	npt_element=hashtb_n(nlsr->npt);
+
+	for(i=0;i<npt_element;i++)
+	{
+		ne=e->data;
+		
+		int j,k, nl_element,face_list_element;
+		struct face_list_entry *fle;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(ne->face_list, ef);
+		face_list_element=hashtb_n(ne->face_list);
+		if ( face_list_element <= 0 )
+		{
+			printf(" 	Face: No Face \n");
+		}
+		else
+		{
+			for(j=0;j<face_list_element;j++)
+			{
+				fle=ef->data;
+				int check=does_face_exist_for_router(ne->orig_router,fle->next_hop_face);
+				if ( check == 0 )
+				{
+					struct name_list_entry *nle;		
+					struct hashtb_enumerator eenle;
+    					struct hashtb_enumerator *enle = &eenle;
+
+					hashtb_start(ne->name_list, enle);
+					nl_element=hashtb_n(ne->name_list);	
+
+					for (k=0;k<nl_element;k++)
+					{
+						nle=enle->data;
+
+						//delete all the fib entries here		
+
+						hashtb_next(enle);
+					}
+					hashtb_end(enle);
+
+					char faceid[20];
+					memset(faceid,0,20);
+					sprintf(faceid,"%d",fle->next_hop_face);
+					char *evdata=(char *)malloc(strlen(ne->orig_router)+strlen(faceid)+2);
+					memset(evdata,0,strlen(ne->orig_router)+strlen(faceid)+2);					
+					memcpy(evdata+strlen(evdata),ne->orig_router,strlen(ne->orig_router));	
+					memcpy(evdata+strlen(evdata),"|",1);
+					memcpy(evdata+strlen(evdata),faceid,strlen(faceid));					
+	
+					nlsr->event = ccn_schedule_event(nlsr->sched, 1, &delete_old_face_from_npt, (void *)evdata, 0);					
+					
+				}
+				
+				hashtb_next(ef);	
+			}
+		}
+		hashtb_end(ef);
+		
+			
+		hashtb_next(e);		
+	}
+
+	hashtb_end(e);
+
+}
+
+void
+update_npt_with_new_route()
+{
+	clean_old_fib_entries_from_npt();
+	add_new_fib_entries_to_npt();
+}
+
 void 
 destroy_all_face_by_nlsr(void)
 {
@@ -360,10 +738,12 @@
 		for (j=0;j<nl_element;j++)
 		{
 			nle=enle->data;
+			/*
 			if ( ne->next_hop_face != NO_FACE)
 			{
 				add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)nle->name, OP_UNREG , ne->next_hop_face);
 			}
+			*/
 			//printf(" Name Prefix: %s Face: %d \n",nle->name,ne->next_hop_face);
 			hashtb_next(enle);
 		}
diff --git a/nlsr_npt.h b/nlsr_npt.h
index f469f24..ae4f123 100644
--- a/nlsr_npt.h
+++ b/nlsr_npt.h
@@ -7,7 +7,8 @@
 {
 	char *orig_router;
 	struct hashtb *name_list;
-	int next_hop_face;
+	//int next_hop_face;
+	struct hashtb *face_list;
 };
 
 struct name_list_entry
@@ -16,11 +17,12 @@
 };
 
 
-int add_npt_entry(char *orig_router, char *name_prefix, int face);
+int add_npt_entry(char *orig_router, char *name_prefix, int num_face, int *faces, int *route_costs);
 int delete_npt_entry(char *orig_router, char *name_prefix);
 void print_npt(void);
-void delete_orig_router_from_npt(char *orig_router,int next_hop_face);
-void update_npt_with_new_route(char * orig_router,int next_hop_face);
+void delete_orig_router_from_npt(char *orig_router);
+//void update_npt_with_new_route(char * orig_router,int next_hop_face);
+void update_npt_with_new_route();
 void destroy_all_face_by_nlsr(void);
 
 #endif
diff --git a/nlsr_route.c b/nlsr_route.c
index f45c20b..1d8bc42 100644
--- a/nlsr_route.c
+++ b/nlsr_route.c
@@ -24,6 +24,7 @@
 #include "nlsr_lsdb.h"
 #include "nlsr_npt.h"
 #include "nlsr_adl.h"
+#include "nlsr_fib.h"
 
 int
 route_calculate(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags)
@@ -53,7 +54,8 @@
 		print_rev_map();
 
 		do_old_routing_table_updates();
-	
+		clear_old_routing_table();	
+		print_routing_table();
 
 		int i;
 		int **adj_matrix;
@@ -68,14 +70,17 @@
 
 		long int source=get_mapping_no(nlsr->router_name);
 		long int *parent=(long int *)malloc(map_element * sizeof(long int));
+		long int *dist=(long int *)malloc(map_element * sizeof(long int));
 
-		calculate_path(adj_matrix,parent, map_element, source);
+		calculate_path(adj_matrix,parent,dist, map_element, source);
 		
 		print_all_path_from_source(parent,source);
 
 		print_all_next_hop(parent,source);		
 
-		update_routing_table_with_new_route(parent,source);
+		update_routing_table_with_new_route(parent, dist,source);
+
+		update_npt_with_new_route();
 
 		print_routing_table();
 		print_npt();
@@ -85,6 +90,7 @@
 			free(adj_matrix[i]);
 		}
 		free(parent);
+		free(dist);
 		free(adj_matrix);
 		hashtb_destroy(&nlsr->map);
 		hashtb_destroy(&nlsr->rev_map);
@@ -98,11 +104,11 @@
 }
 
 void 
-calculate_path(int **adj_matrix, long int *parent, long int V, long int S)
+calculate_path(int **adj_matrix, long int *parent,long int *dist ,long int V, long int S)
 {
 	int i;
 	long int v,u;
-	long int *dist=(long int *)malloc(V * sizeof(long int));
+	//long int *dist=(long int *)malloc(V * sizeof(long int));
 	long int *Q=(long int *)malloc(V * sizeof(long int));
 	long int head=0;
 	/* Initial the Parent */
@@ -148,7 +154,7 @@
 	}
 
 	free(Q);
-	free(dist);	
+	//free(dist);	
 }
 
 void
@@ -615,8 +621,9 @@
 	}
 }
 
+
 int 
-get_next_hop(char *dest_router)
+get_number_of_next_hop(char *dest_router)
 {
 	struct routing_table_entry *rte;
 
@@ -630,7 +637,56 @@
 	if( res == HT_OLD_ENTRY )
 	{
 		rte=e->data;
-		ret=rte->next_hop_face;
+		ret=hashtb_n(rte->face_list);
+		//nhl=rte->face_list;
+	}
+	else if(res == HT_NEW_ENTRY)
+	{
+		hashtb_delete(e);
+		ret=NO_NEXT_HOP;
+	}
+
+	hashtb_end(e);	
+
+	return ret;
+}
+
+
+int 
+get_next_hop(char *dest_router,int *faces, int *route_costs)
+{
+	struct routing_table_entry *rte;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee; 	
+    	int res,ret;
+
+   	hashtb_start(nlsr->routing_table, e);
+    	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);
+
+	if( res == HT_OLD_ENTRY )
+	{
+		rte=e->data;
+		ret=hashtb_n(rte->face_list);
+		//nhl=rte->face_list;
+		int j,face_list_element;
+		struct face_list_entry *fle;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(rte->face_list, ef);
+		face_list_element=hashtb_n(rte->face_list);
+		for(j=0;j<face_list_element;j++)
+		{
+			fle=ef->data;
+			//printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
+			faces[j]=fle->next_hop_face;
+			route_costs[j]=fle->route_cost;
+			hashtb_next(ef);	
+		}
+		hashtb_end(ef);
+		
 	}
 	else if(res == HT_NEW_ENTRY)
 	{
@@ -666,7 +722,11 @@
 		rte->dest_router=(char *)malloc(strlen(dest_router)+1);
 		memset(rte->dest_router,0,strlen(dest_router)+1);
 		memcpy(rte->dest_router,dest_router,strlen(dest_router));
-		rte->next_hop_face=NO_NEXT_HOP;
+		//rte->next_hop_face=NO_NEXT_HOP;
+		struct hashtb_param param_fle = {0};
+		rte->face_list=hashtb_create(sizeof(struct face_list_entry), &param_fle);
+
+		add_npt_entry(dest_router, dest_router, 0, NULL, NULL);
 	}
 	hashtb_end(e);
 
@@ -715,9 +775,9 @@
 }
 
 void 
-update_routing_table(char * dest_router,int next_hop_face)
+update_routing_table(char * dest_router,int next_hop_face, int route_cost)
 {
-	int res;
+	int res,res1;
 	struct routing_table_entry *rte;
 
 	struct hashtb_enumerator ee;
@@ -729,7 +789,40 @@
 	if( res == HT_OLD_ENTRY )
 	{
 		rte=e->data;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(rte->face_list, ef);
+		res1 = hashtb_seek(ef, &next_hop_face, sizeof(next_hop_face), 0);	
+		if( res1 == HT_NEW_ENTRY)
+		{
+			struct face_list_entry *fle=(struct face_list_entry *)malloc(sizeof(struct face_list_entry));
+			fle=ef->data;
+			fle->next_hop_face=next_hop_face;
+			fle->route_cost=route_cost;						
+		}
+		else if ( res1 == HT_OLD_ENTRY )
+		{
+			struct face_list_entry *fle;
+			fle=ef->data;
+			fle->route_cost=route_cost;
+		}
+		hashtb_end(ef);
+		
+		/*
+		//updating the face for the router prefix itself
+		if ( (rte->next_hop_face != NO_FACE  || rte->next_hop_face != NO_NEXT_HOP ) && is_neighbor(dest_router)==0 )
+		{
+			add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)dest_router, OP_UNREG, rte->next_hop_face);
+		}
+		if ( (next_hop_face != NO_FACE  || next_hop_face != NO_NEXT_HOP ) && is_neighbor(dest_router)==0 )
+		{
+			add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)dest_router, OP_REG, next_hop_face);
+		}
+
 		rte->next_hop_face=next_hop_face;
+		*/
 	}
 	else if ( res == HT_OLD_ENTRY )
 	{
@@ -745,7 +838,7 @@
 {
 	printf("\n");
 	printf("print_routing_table called\n");
-	int i, rt_element;
+	int i,j, rt_element,face_list_element;
 	
 	struct routing_table_entry *rte;
 
@@ -760,7 +853,30 @@
 		printf("----------Routing Table Entry %d------------------\n",i+1);
 		rte=e->data;
 		printf(" Destination Router: %s \n",rte->dest_router);
-		rte->next_hop_face == NO_NEXT_HOP ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", rte->next_hop_face);
+		//rte->next_hop_face == NO_NEXT_HOP ? printf(" Next Hop Face: NO_NEXT_HOP \n") : printf(" Next Hop Face: %d \n", rte->next_hop_face);
+
+		struct face_list_entry *fle;
+
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(rte->face_list, ef);
+		face_list_element=hashtb_n(rte->face_list);
+		if ( face_list_element <= 0 )
+		{
+			printf(" 	Face: No Face \n");
+		}
+		else
+		{
+			for(j=0;j<face_list_element;j++)
+			{
+				fle=ef->data;
+				printf(" 	Face: %d Route_Cost: %d \n",fle->next_hop_face,fle->route_cost);
+				hashtb_next(ef);	
+			}
+		}
+		hashtb_end(ef);
+
 		hashtb_next(e);		
 	}
 
@@ -780,6 +896,7 @@
  	 	return -1;
 	}
 
+	//struct routing_table_entry *rte;
 	int res;
 	struct hashtb_enumerator ee;
     	struct hashtb_enumerator *e = &ee;
@@ -789,6 +906,16 @@
 	
 	if ( res == HT_OLD_ENTRY )
 	{
+		//rte=e->data;
+
+		/*		
+	
+		if ( (rte->next_hop_face != NO_FACE  || rte->next_hop_face != NO_NEXT_HOP) && is_neighbor(ev->evdata)==0 )
+		{
+			add_delete_ccn_face_by_face_id(nlsr->ccn, (const char *)ev->evdata, OP_UNREG, rte->next_hop_face);
+		}
+
+		*/
 		hashtb_delete(e);
 	}
 	else if ( res == HT_NEW_ENTRY )
@@ -796,9 +923,38 @@
 		hashtb_delete(e);
 	}
 
+	print_routing_table();
+	
 	return 0;
 }
 
+void 
+clear_old_routing_table()
+{
+	printf("clear_old_routing_table called\n");
+	int i,rt_element;
+	
+	struct routing_table_entry *rte;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->routing_table, e);
+	rt_element=hashtb_n(nlsr->routing_table);
+
+	for(i=0;i<rt_element;i++)
+	{
+		rte=e->data;
+		hashtb_destroy(&rte->face_list);
+		struct hashtb_param param_fle = {0};
+		rte->face_list=hashtb_create(sizeof(struct face_list_entry), &param_fle);
+
+		hashtb_next(e);		
+	}
+
+	hashtb_end(e);	
+}
+
 
 void 
 do_old_routing_table_updates()
@@ -821,7 +977,7 @@
 		mapping_no=get_mapping_no(rte->dest_router);
 		if ( mapping_no == NO_MAPPING_NUM)
 		{		
-			delete_orig_router_from_npt(rte->dest_router,rte->next_hop_face);
+			delete_orig_router_from_npt(rte->dest_router);
 			char *router=(char *)malloc(strlen(rte->dest_router)+1);
 			memset(router,0,strlen(rte->dest_router)+1);
 			memcpy(router,rte->dest_router,strlen(rte->dest_router)+1);
@@ -833,8 +989,10 @@
 	hashtb_end(e);	
 }
 
+
+
 void 
-update_routing_table_with_new_route(long int *parent, long int source)
+update_routing_table_with_new_route(long int *parent, long int *dist,long int source)
 {
 	printf("update_routing_table_with_new_route called\n");
 	int i, map_element;
@@ -859,7 +1017,7 @@
 				//printf(" Next hop router Num: %d ",next_hop_router_num);
 				if ( next_hop_router_num == NO_NEXT_HOP )
 				{
-					update_npt_with_new_route(orig_router,NO_FACE);
+					//update_npt_with_new_route(orig_router,NO_FACE);
 					printf ("\nOrig_router: %s Next Hop Face: %d \n",orig_router,NO_FACE);
 				}
 				else 
@@ -867,8 +1025,8 @@
 					char *next_hop_router=get_router_from_rev_map(next_hop_router_num);
 					//printf("Next hop router name: %s \n",next_hop_router);
 					int next_hop_face=get_next_hop_face_from_adl(next_hop_router);
-					update_npt_with_new_route(orig_router,next_hop_face);
-					update_routing_table(orig_router,next_hop_face);
+					//update_npt_with_new_route(orig_router,next_hop_face);
+					update_routing_table(orig_router,next_hop_face,dist[me->mapping]);
 					printf ("Orig_router: %s Next Hop Face: %d \n",orig_router,next_hop_face);
 
 				}
@@ -880,3 +1038,44 @@
 	hashtb_end(e);
 }
 
+int 
+does_face_exist_for_router(char *dest_router, int face_id)
+{
+	int ret=0;
+
+	int res,res1;
+	struct routing_table_entry *rte;
+
+	struct hashtb_enumerator ee;
+    	struct hashtb_enumerator *e = &ee;
+    	
+    	hashtb_start(nlsr->routing_table, e);
+	res = hashtb_seek(e, dest_router, strlen(dest_router), 0);
+
+	if( res == HT_OLD_ENTRY )
+	{
+		rte=e->data;
+		struct hashtb_enumerator eef;
+    		struct hashtb_enumerator *ef = &eef;
+    	
+    		hashtb_start(rte->face_list, ef);
+		res1 = hashtb_seek(ef, &face_id, sizeof(face_id), 0);	
+		if( res1 == HT_OLD_ENTRY)
+		{
+			ret=1;									
+		}
+		else if ( res1 == HT_OLD_ENTRY )
+		{
+			hashtb_delete(ef);
+		}
+		hashtb_end(ef);
+	}
+	else if( res == HT_NEW_ENTRY )
+	{
+		hashtb_delete(e);
+	} 
+	
+	hashtb_end(e);
+
+	return ret;
+}
diff --git a/nlsr_route.h b/nlsr_route.h
index 5361deb..021429d 100644
--- a/nlsr_route.h
+++ b/nlsr_route.h
@@ -17,9 +17,15 @@
 struct routing_table_entry
 {
 	char *dest_router;
+	//int next_hop_face;
+	struct hashtb *face_list;
+};
+
+struct face_list_entry
+{
 	int next_hop_face;
-}
-;
+	int route_cost;
+};
 
 int route_calculate(struct ccn_schedule *sched, void *clienth, struct ccn_scheduled_event *ev, int flags);
 void make_map(void);
@@ -31,7 +37,7 @@
 void init_adj_matrix(int **adj_matrix,int map_element);
 void print_adj_matrix(int **adj_matrix, int map_element);
 int get_mapping_no(char *router);
-void calculate_path(int **adj_matrix, long int *parent, long int V, long int S);
+void calculate_path(int **adj_matrix, long int *parent,long int *dist, long int V, long int S);
 void sort_queue_by_distance(long int *Q,long int *dist,long int start,long int element);
 int is_not_explored(long int *Q, long int u,long int start, long int element);
 void print_path(long int *parent, long int dest);
@@ -42,14 +48,17 @@
 
 /* Routing Table Relates function */
 
-int get_next_hop(char *dest_router);
+int get_next_hop(char *dest_router,int *faces, int *route_costs);
+int get_number_of_next_hop(char *dest_router);
 void add_next_hop_router(char *dest_router);
 void add_next_hop_from_lsa_adj_body(char *body, int no_link);
 void print_routing_table(void);
 void do_old_routing_table_updates();
-void update_routing_table_with_new_route(long int *parent, long int source);
+void clear_old_routing_table();
+void update_routing_table_with_new_route(long int *parent,long int *dist, long int source);
 
 long int get_next_hop_from_calculation(long int *parent, long int dest,long int source);
 void print_all_next_hop(long int *parent,long int source);
+int does_face_exist_for_router(char *dest_router, int face_id);
 
 #endif