int nsm_adj_ok (struct ospf_neighbor *nbr) { struct ospf_interface *oi; int next_state; int flag = 0; oi = nbr->oi; next_state = nbr->state; /* These netowork types must be adjacency. */ if (oi->type == OSPF_IFTYPE_POINTOPOINT || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || oi->type == OSPF_IFTYPE_VIRTUALLINK) flag = 1; /* Router itself is the DRouter or the BDRouter. */ if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi))) flag = 1; if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi)) || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi))) flag = 1; if (nbr->state == NSM_TwoWay && flag == 1) next_state = NSM_ExStart; else if (nbr->state >= NSM_ExStart && flag == 0) next_state = NSM_TwoWay; return next_state; }
int ospf_dr_election (struct ospf_interface *oi) { struct in_addr old_dr, old_bdr; int old_state, new_state; struct list *el_list; struct ospf_neighbor *dr, *bdr; /* backup current values. */ old_dr = DR (oi); old_bdr = BDR (oi); old_state = oi->state; el_list = list_new (); /* List eligible routers. */ ospf_dr_eligible_routers (oi->nbrs, el_list); /* First election of DR and BDR. */ bdr = ospf_elect_bdr (oi, el_list); dr = ospf_elect_dr (oi, el_list); new_state = ospf_ism_state (oi); zlog_info ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi))); zlog_info ("DR-Election[1st]: DR %s", inet_ntoa (DR (oi))); if (new_state != old_state && !(new_state == ISM_DROther && old_state < ISM_DROther)) { ospf_elect_bdr (oi, el_list); ospf_elect_dr (oi, el_list); new_state = ospf_ism_state (oi); zlog_info ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi))); zlog_info ("DR-Election[2nd]: DR %s", inet_ntoa (DR (oi))); } list_delete (el_list); /* if DR or BDR changes, cause AdjOK? neighbor event. */ if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) || !IPV4_ADDR_SAME (&old_bdr, &BDR (oi))) ospf_dr_change (oi->ospf, oi->nbrs); if (oi->type == OSPF_IFTYPE_BROADCAST || oi->type == OSPF_IFTYPE_POINTOPOINT) { /* Multicast group change. */ if ((old_state != ISM_DR && old_state != ISM_Backup) && (new_state == ISM_DR || new_state == ISM_Backup)) ospf_if_add_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex); else if ((old_state == ISM_DR || old_state == ISM_Backup) && (new_state != ISM_DR && new_state != ISM_Backup)) ospf_if_drop_alldrouters (oi->ospf, oi->address, oi->ifp->ifindex); } return new_state; }
static int ospf_dr_election (struct ospf_interface *oi) { struct in_addr old_dr, old_bdr; int old_state, new_state; struct list *el_list; struct ospf_neighbor *dr, *bdr; /* backup current values. */ old_dr = DR (oi); old_bdr = BDR (oi); old_state = oi->state; el_list = list_new (); /* List eligible routers. */ ospf_dr_eligible_routers (oi->nbrs, el_list); /* First election of DR and BDR. */ bdr = ospf_elect_bdr (oi, el_list); dr = ospf_elect_dr (oi, el_list); new_state = ospf_ism_state (oi); zlog_info ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi))); zlog_info ("DR-Election[1st]: DR %s", inet_ntoa (DR (oi))); if (new_state != old_state && !(new_state == ISM_DROther && old_state < ISM_DROther)) { ospf_elect_bdr (oi, el_list); ospf_elect_dr (oi, el_list); new_state = ospf_ism_state (oi); zlog_info ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi))); zlog_info ("DR-Election[2nd]: DR %s", inet_ntoa (DR (oi))); } list_delete (el_list); /* if DR or BDR changes, cause AdjOK? neighbor event. */ if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) || !IPV4_ADDR_SAME (&old_bdr, &BDR (oi))) ospf_dr_change (oi->ospf, oi->nbrs); return new_state; }
int nsm_twoway_received (struct ospf_neighbor *nbr) { struct ospf_interface *oi; int next_state = NSM_TwoWay; oi = nbr->oi; /* These netowork types must be adjacency. */ if (oi->type == OSPF_IFTYPE_POINTOPOINT || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || oi->type == OSPF_IFTYPE_VIRTUALLINK) next_state = NSM_ExStart; /* Router itself is the DRouter or the BDRouter. */ if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi))) next_state = NSM_ExStart; /* Neighboring Router is the DRouter or the BDRouter. */ if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router) || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)) next_state = NSM_ExStart; return next_state; }
struct ospf_neighbor * ospf_elect_bdr (struct ospf_interface *oi, struct list *el_list) { struct list *bdr_list, *no_dr_list; struct listnode *node; struct ospf_neighbor *nbr, *bdr = NULL; bdr_list = list_new (); no_dr_list = list_new (); /* Add neighbors to the list. */ for (node = listhead (el_list); node; nextnode (node)) { nbr = getdata (node); /* neighbor declared to be DR. */ if (NBR_IS_DR (nbr)) continue; /* neighbor declared to be BDR. */ if (NBR_IS_BDR (nbr)) listnode_add (bdr_list, nbr); listnode_add (no_dr_list, nbr); } /* Elect Backup Designated Router. */ if (listcount (bdr_list) > 0) bdr = ospf_dr_election_sub (bdr_list); else bdr = ospf_dr_election_sub (no_dr_list); /* Set BDR to interface. */ if (bdr) { BDR (oi) = bdr->address.u.prefix4; bdr->bd_router = bdr->address.u.prefix4; } else BDR (oi).s_addr = 0; list_delete (bdr_list); list_delete (no_dr_list); return bdr; }
static int ospf_ism_state(struct ospf_interface *oi) { if (IPV4_ADDR_SAME(&DR(oi), &oi->address->u.prefix4)) return ISM_DR; else if (IPV4_ADDR_SAME(&BDR(oi), &oi->address->u.prefix4)) return ISM_Backup; else return ISM_DROther; }
/* 10.4 of RFC2328, indicate whether an adjacency is appropriate with * the given neighbour */ static int nsm_should_adj (struct ospf_neighbor *nbr) { struct ospf_interface *oi = nbr->oi; /* These network types must always form adjacencies. */ if (oi->type == OSPF_IFTYPE_POINTOPOINT || oi->type == OSPF_IFTYPE_POINTOMULTIPOINT || oi->type == OSPF_IFTYPE_VIRTUALLINK /* Router itself is the DRouter or the BDRouter. */ || IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi)) || IPV4_ADDR_SAME (&oi->address->u.prefix4, &BDR (oi)) /* Neighboring Router is the DRouter or the BDRouter. */ || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &DR (oi)) || IPV4_ADDR_SAME (&nbr->address.u.prefix4, &BDR (oi))) return 1; return 0; }
void ospf_nbr_state_message(struct ospf_neighbor *nbr, char *buf, size_t size) { int state; struct ospf_interface *oi = nbr->oi; if (IPV4_ADDR_SAME(&DR(oi), &nbr->address.u.prefix4)) state = ISM_DR; else if (IPV4_ADDR_SAME(&BDR(oi), &nbr->address.u.prefix4)) state = ISM_Backup; else state = ISM_DROther; snprintf(buf, size, "%s/%s", lookup_msg(ospf_nsm_state_msg, nbr->state, NULL), lookup_msg(ospf_ism_state_msg, state, NULL)); }
struct ospf_neighbor * ospf_elect_dr (struct ospf_interface *oi, struct list *el_list) { struct list *dr_list; struct listnode *node; struct ospf_neighbor *nbr, *dr = NULL, *bdr = NULL; dr_list = list_new (); /* Add neighbors to the list. */ for (node = listhead (el_list); node; nextnode (node)) { nbr = getdata (node); /* neighbor declared to be DR. */ if (NBR_IS_DR (nbr)) listnode_add (dr_list, nbr); /* Preserve neighbor BDR. */ if (IPV4_ADDR_SAME (&BDR (oi), &nbr->address.u.prefix4)) bdr = nbr; } /* Elect Designated Router. */ if (listcount (dr_list) > 0) dr = ospf_dr_election_sub (dr_list); else dr = bdr; /* Set DR to interface. */ if (dr) { DR (oi) = dr->address.u.prefix4; dr->d_router = dr->address.u.prefix4; } else DR (oi).s_addr = 0; list_delete (dr_list); return dr; }
static int DecodeACSign(WinZipJPEGDecompressor *self,int comp,unsigned int k,int absvalue, const WinZipJPEGBlock *current,const WinZipJPEGBlock *north,const WinZipJPEGBlock *west, const WinZipJPEGQuantizationTable *quantization) { // Decode sign. (5.6.6.4) // Calculate sign context, or decode with fixed probability. (5.6.6.4.1) int predictedsign; if(IsFirstRowOrColumn(k)) { int bdr=BDR(k,current,north,west,quantization); if(bdr==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext); predictedsign=(bdr<0); } else if(k==4) { int sign1=Sign(north->c[k]); int sign2=Sign(west->c[k]); if(sign1+sign2==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext); predictedsign=(sign1+sign2<0); } else if(IsSecondRow(k)) { if(north->c[k]==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext); predictedsign=(north->c[k]<0); } else if(IsSecondColumn(k)) { if(west->c[k]==0) return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext); predictedsign=(west->c[k]<0); } else { return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,&self->fixedcontext); } static const int n_for_k[64]={ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0,11,12, 13,14, 0, 0,15,16, 17,18, 0, 0, 0,19,20, 21,22, 0, 0, 0, 0,23,24, 25, 0, 0, 0, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; int n=n_for_k[k]; int signcontext1=Min(Category(absvalue)/2,2); return NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder, &self->acsignbins[comp][n][signcontext1][predictedsign]); }
static int DecodeACComponent(WinZipJPEGDecompressor *self,int comp,unsigned int k,bool canbezero, const WinZipJPEGBlock *current,const WinZipJPEGBlock *north,const WinZipJPEGBlock *west, const WinZipJPEGQuantizationTable *quantization) { if(!north) north=&ZeroBlock; if(!west) west=&ZeroBlock; int val1; if(IsFirstRowOrColumn(k)) val1=Abs(BDR(k,current,north,west,quantization)); else val1=Average(k,north,west,quantization); int val2=Sum(k,current); if(canbezero) { // Decode zero/non-zero bit. (5.6.6.1) int zerocontext1=Min(Category(val1),2); int zerocontext2=Min(Category(val2),5); int nonzero=NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder, &self->zerobins[comp][k-1][zerocontext1][zerocontext2]); // If this component is zero, there is no need to decode further parameters. if(!nonzero) return 0; } // This component is not zero. Proceed with decoding absolute value. int absvalue; // Decode pivot (abs>=2). (5.6.6.2) int pivotcontext1=Min(Category(val1),4); int pivotcontext2=Min(Category(val2),6); int pivot=NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder, &self->pivotbins[comp][k-1][pivotcontext1][pivotcontext2]); if(!pivot) { // The absolute of this component is not >=2. It must therefore be 1, // and there is no need to decode the value. absvalue=1; } else { // The absolute of this component is >=2. Proceed with decoding // the absolute value. (5.6.6.3) int val3,n; if(IsFirstRow(k)) { val3=Column(k)-1; n=0; } else if(IsFirstColumn(k)) { val3=Row(k)-1; n=1; } else { val3=Category(k-4); n=2; } int magnitudecontext1=Min(Category(val1),8); int magnitudecontext2=Min(Category(val2),8); int remaindercontext=val3; // Decode absolute value. absvalue=DecodeBinarization(&self->decoder, self->acmagnitudebins[comp][n][magnitudecontext1][magnitudecontext2], self->acremainderbins[comp][n][remaindercontext], 14,9)+2; } if(DecodeACSign(self,comp,k,absvalue,current,north,west,quantization)) return -absvalue; else return absvalue; }
static void CompressACSign(JPEGCompressor *self,int comp,unsigned int k,int absvalue, const JPEGBlock *current,const JPEGBlock *north,const JPEGBlock *west, const JPEGQuantizationTable *quantization) { int sign=current->c[k]<0; // Calculate sign context, or compress with fixed probability. int predictedsign; if(IsFirstRowOrColumn(k)) { int bdr=BDR(k,current,north,west,quantization); if(bdr==0) { WriteBit(&self->encoder,sign,0x800); return; } predictedsign=(bdr<0); } else if(k==4) { int sign1=Sign(north->c[k]); int sign2=Sign(west->c[k]); if(sign1+sign2==0) { WriteBit(&self->encoder,sign,0x800); return; } predictedsign=(sign1+sign2<0); } else if(IsSecondRow(k)) { if(north->c[k]==0) { WriteBit(&self->encoder,sign,0x800); return; } predictedsign=(north->c[k]<0); } else if(IsSecondColumn(k)) { if(west->c[k]==0) { WriteBit(&self->encoder,sign,0x800); return; } predictedsign=(west->c[k]<0); } else { WriteBit(&self->encoder,sign,0x800); return; } static const int n_for_k[64]={ 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0,11,12, 13,14, 0, 0,15,16, 17,18, 0, 0, 0,19,20, 21,22, 0, 0, 0, 0,23,24, 25, 0, 0, 0, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; int n=n_for_k[k]; int signcontext1=Min(Category(absvalue)/2,2); WriteDynamicBit(&self->encoder,sign, &self->acsignbins[comp][n][signcontext1][predictedsign], self->acsignshift); }
static void CompressACComponent(JPEGCompressor *self,int comp,unsigned int k,bool canbezero, const JPEGBlock *current,const JPEGBlock *north,const JPEGBlock *west, const JPEGQuantizationTable *quantization) { int value=current->c[k]; if(!north) north=&ZeroBlock; if(!west) west=&ZeroBlock; int val1; if(IsFirstRowOrColumn(k)) val1=Abs(BDR(k,current,north,west,quantization)); else val1=Average(k,north,west,quantization); int val2=Sum(k,current); if(canbezero) { // Compress zero/non-zero bit. int zerocontext1=Min(Category(val1),2); int zerocontext2=Min(Category(val2),5); WriteDynamicBit(&self->encoder,value!=0, &self->zerobins[comp][k-1][zerocontext1][zerocontext2], self->zeroshift); // If this component is zero, there is no need to compress further parameters. if(value==0) return; } // This component is not zero. Proceed with compressing absolute value. int absvalue=Abs(value); // Compress pivot (abs>=2). int pivotcontext1=Min(Category(val1),4); int pivotcontext2=Min(Category(val2),6); WriteDynamicBit(&self->encoder,absvalue>1, &self->pivotbins[comp][k-1][pivotcontext1][pivotcontext2], self->pivotshift); if(absvalue>1) { // The absolute of this component is >=2. Proceed with compressing // the absolute value. int val3,n; if(IsFirstRow(k)) { val3=Column(k)-1; n=0; } else if(IsFirstColumn(k)) { val3=Row(k)-1; n=1; } else { val3=Category(k-4); n=2; } int magnitudecontext1=Min(Category(val1),8); int magnitudecontext2=Min(Category(val2),8); int remaindercontext=val3; // Compress absolute value. WriteUniversalCode(&self->encoder,absvalue-2, self->acmagnitudebins[comp][n][magnitudecontext1][magnitudecontext2], self->acmagnitudeshift, self->acremainderbins[comp][n][remaindercontext], self->acremaindershift); } CompressACSign(self,comp,k,absvalue,current,north,west,quantization); }